1 /*****************************************************************************\
2      Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3                 This file is licensed under the Snes9x License.
4    For further information, consult the LICENSE file in the root directory.
5 \*****************************************************************************/
6 
7 /***********************************************************************************
8   SNES9X for Mac OS (c) Copyright John Stiles
9 
10   Snes9x for Mac OS X
11 
12   (c) Copyright 2001 - 2011  zones
13   (c) Copyright 2002 - 2005  107
14   (c) Copyright 2002         PB1400c
15   (c) Copyright 2004         Alexander and Sander
16   (c) Copyright 2004 - 2005  Steven Seeger
17   (c) Copyright 2005         Ryan Vogt
18  ***********************************************************************************/
19 
20 
21 #include "snes9x.h"
22 #include "memmap.h"
23 #include "blit.h"
24 
25 #include <OpenGL/OpenGL.h>
26 #define __STDC_FORMAT_MACROS
27 #include <inttypes.h>
28 
29 #include "mac-prefix.h"
30 #include "mac-audio.h"
31 #include "mac-cart.h"
32 #include "mac-coreimage.h"
33 #include "mac-dialog.h"
34 #include "mac-file.h"
35 #include "mac-keyboard.h"
36 #include "mac-os.h"
37 #include "mac-render.h"
38 #include "mac-snes9x.h"
39 #include "mac-stringtools.h"
40 #include "mac-prefs.h"
41 
42 enum
43 {
44 	iNibGFullScreen = 1,
45 	iNibGSwitchResolution,
46 	iNibGShowFrameRate,
47 	iNibGCIFilterEnable,
48 	iNibGTransparency,
49 	iNibGGL32bit,
50 	iNibGGLStretch,
51 	iNibGCoreImageFilter,
52 	iNibGVideoMode,
53 	iNibGDirectMP,
54 	iNibGGLVSync,
55 	iNibGDrawOverscan,
56 	iNibGScreenCurvature,
57 	iNibGCurvatureWarp,
58 	iNibGAspectRatio,
59 	iNibGAspectRatioText,
60 
61 	iNibSSynchronize = 201,
62 	iNibS16BitPlayback,
63 	iNibSStereo,
64 	iNibSReverseStereo,
65 	iNibSPlaybackRate,
66 	iNibSBufferSize,
67 	iNibSVolume,
68 	iNibSInputRate,
69 	iNibSInputRateText,
70 	iNibSAllowLag,
71 	iNibSInterval,
72 
73 	iNibOSaveFolder = 401,
74 	iNibOAutoSaveInterval,
75 
76 	iNibMCPUCycles = 601,
77 	iNibMReserved1,
78 	iNibMTurboSkipArrows,
79 	iNibMTurboSkipText,
80 	iNibMFrameSkip,
81 	iNibMAllowInvalidVRAMAccess,
82 	iNibMAllowSpecificGameHacks,
83 
84 	iNibXStartOpenDialog = 801,
85 	iNibXShowTimeInFrz,
86 	iNibXMusicBoxMode,
87 	iNibXEnableToggle,
88 	iNibXBSXBootup,
89 	iNibXSaveWindowPos,
90 	iNibXUseIPSPatch,
91 	iNibXOnScreenInfo,
92 	iNibXInactiveMode
93 };
94 
95 enum
96 {
97 	iOpenGLBlocky = 1,
98 	iOpenGLTVMode,
99 	iOpenGLSmoothMode,
100 	iOpenGLBlendMode,
101 	iOpenGLEagleMode,
102 	iOpenGL2xSAIMode,
103 	iOpenGLSuper2xSAIMode,
104 	iOpenGLEPXMode,
105 	iOpenGLHQ2xMode,
106 	iOpenGLHQ3xMode,
107 	iOpenGLHQ4xMode,
108 	iOpenGLNTSC_CMode,
109 	iOpenGLNTSC_SMode,
110 	iOpenGLNTSC_RMode,
111 	iOpenGLNTSC_MMode,
112 	iOpenGLNTSC_TV_CMode,
113 	iOpenGLNTSC_TV_SMode,
114 	iOpenGLNTSC_TV_RMode,
115 	iOpenGLNTSC_TV_MMode
116 };
117 
118 enum
119 {
120 	iNibSaveFolderNameMenuItem  = 5
121 };
122 
123 static int	lastTabIndex = 1;
124 static int	tabList[]    = { 5, 129, 130, 131, 132, 133 };
125 
126 struct PrefList
127 {
128 	OSType	itemName;
129 	void	*itemPointer;
130 	int		size;
131 };
132 
133 static PrefList	prefList[] =
134 {
135 	{ 'flsc', &fullscreen,									sizeof(bool8      ) },
136 	{ 'reso', &autoRes,										sizeof(bool8      ) },
137 	{ 'dfps', &Settings.DisplayFrameRate,					sizeof(bool8      ) },
138 	{ 'tran', &Settings.Transparency,						sizeof(bool8      ) },
139 	{ 'gl32', &gl32bit,										sizeof(bool8      ) },
140 	{ 'glst', &glstretch,									sizeof(bool8      ) },
141 	{ 'draw', &drawingMethod,								sizeof(long       ) },
142 	{ 'Vmod', &videoMode,									sizeof(int        ) },
143 	{ 'MPmt', &multiprocessor,								sizeof(bool8      ) },
144 	{ 'VSNC', &vsync,										sizeof(bool8      ) },
145 	{ 'H239', &drawoverscan,								sizeof(bool8      ) },
146 	{ 'SCur', &screencurvature,								sizeof(bool8      ) },
147 	{ 'SCuW', &macCurvatureWarp,							sizeof(int        ) },
148 	{ 'ASPe', &macAspectRatio,								sizeof(int        ) },
149 	{ 'CIFl', &ciFilterEnable,							    sizeof(bool8      ) },
150 
151 	{ 'sSyn', &Settings.SoundSync,					        sizeof(bool8      ) },
152 	{ 'srat', &Settings.SoundPlaybackRate,					sizeof(uint32     ) },
153 	{ 'InRt', &Settings.SoundInputRate,						sizeof(uint32     ) },
154 	{ 'MxIv', &macSoundInterval_ms,					        sizeof(uint32     ) },
155 	{ 'SBuf', &macSoundBuffer_ms,					        sizeof(uint32     ) },
156 	{ 'Volm', &macSoundVolume,								sizeof(SInt32     ) },
157 	{ 'AUef', &aueffect,									sizeof(uint16     ) },
158 	{ 'AUce', &cureffect,									sizeof(int        ) },
159 
160 	{ 'romf', &saveInROMFolder,								sizeof(uint8      ) },
161 	{ 'atsv', &Settings.AutoSaveDelay,						sizeof(int32      ) },
162 	{ 'RFlg', &macRecordFlag,								sizeof(uint16     ) },
163 	{ 'PFlg', &macPlayFlag,									sizeof(uint16     ) },
164 	{ 'QTfg', &macQTMovFlag,								sizeof(uint16     ) },
165 
166 	{ 'HHck', &Settings.HDMATimingHack,					    sizeof(int32      ) },
167 	{ 'TbRt', &macFastForwardRate,							sizeof(int        ) },
168 	{ 'FSkp', &macFrameSkip,							    sizeof(int        ) },
169 	{ 'IvVR', &Settings.BlockInvalidVRAMAccessMaster,       sizeof(bool8      ) },
170 	{ 'GSHk', &Settings.DisableGameSpecificHacks,           sizeof(bool8      ) },
171 
172 	{ 'StOp', &startopendlog,								sizeof(bool8      ) },
173 	{ 'STiF', &showtimeinfrz,								sizeof(bool8      ) },
174 	{ 'Togl', &enabletoggle,								sizeof(bool8      ) },
175 	{ 'SvWp', &savewindowpos,								sizeof(bool8      ) },
176 	{ 'OnSc', &onscreeninfo,								sizeof(bool8      ) },
177 	{ 'NIPS', &Settings.NoPatch,							sizeof(bool8      ) },
178 	{ 'BSX_', &Settings.BSXBootup,							sizeof(bool8      ) },
179 	{ 'MbxM', &musicboxmode,								sizeof(int        ) },
180 	{ 'InAc', &inactiveMode,								sizeof(int        ) },
181 
182 	{ 'tab ', &lastTabIndex,								sizeof(int        ) },
183 	{ 'Ftab', &autofireLastTabIndex,						sizeof(int        ) },
184 	{ 'keyb', keyCode,										sizeof(keyCode    ) },
185 	{ 'pset', &padSetting,									sizeof(int        ) },
186 	{ 'dset', &deviceSetting,								sizeof(int        ) },
187 	{ 'chea', &applycheat,									sizeof(bool8      ) },
188 
189 	{ 'ARec', autofireRec,									sizeof(autofireRec) },
190 	{ 'wPos', windowPos,									sizeof(windowPos  ) },
191 	{ 'wSiz', windowSize,									sizeof(windowSize ) },
192 	{ 'wExt', (void *) &windowExtend,						sizeof(bool8      ) },
193 
194 	{ 'NPIP', npServerIP,									sizeof(npServerIP ) },
195 	{ 'NPNM', npName,										sizeof(npName     ) },
196 
197 	{ 'L239', &lastoverscan,								sizeof(bool8      ) },
198 
199 	{ 'ExT1', &(extraOptions.benchmark),					sizeof(bool8      ) },
200 	{ 'ExT2', &(extraOptions.glForceNoTextureRectangle),	sizeof(bool8      ) },
201 	{ 'ExT3', &(extraOptions.glUseClientStrageApple),		sizeof(bool8      ) },
202 	{ 'ExT4', &(extraOptions.glUseTexturePriority),			sizeof(bool8      ) },
203 	{ 'ExT5', &(extraOptions.glStorageHint),				sizeof(int        ) }
204 };
205 
206 #define	kPrefListSize	(sizeof(prefList) / sizeof(prefList[0]))
207 
208 static void SelectTabPane (HIViewRef, SInt16);
209 static pascal void InputRateSliderActionProc (HIViewRef, HIViewPartCode);
210 static pascal void LittleArrowsActionProc (HIViewRef, HIViewPartCode);
211 static pascal OSStatus InputRateTextEventHandler (EventHandlerCallRef, EventRef, void *);
212 static pascal OSStatus AspectRatioTextEventHandler (EventHandlerCallRef, EventRef, void *);
213 static pascal OSStatus TabEventHandler (EventHandlerCallRef, EventRef, void *);
214 static pascal OSStatus PreferencesEventHandler (EventHandlerCallRef, EventRef, void *);
215 
216 
SavePrefs(void)217 void SavePrefs (void)
218 {
219 	CFMutableStringRef	mref;
220 	CFStringRef			sref;
221 	CFDataRef			data;
222 
223 	for (unsigned int i = 0; i < kPrefListSize; i++)
224 	{
225 		mref = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("Preferences_"));
226 		if (mref)
227 		{
228 			sref = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *) &(prefList[i].itemName), sizeof(OSType), kCFStringEncodingMacRoman, false);
229 			if (sref)
230 			{
231 				CFStringAppend(mref, sref);
232 
233 				data = CFDataCreate(kCFAllocatorDefault, (UInt8 *) prefList[i].itemPointer, prefList[i].size);
234 				if (data)
235 				{
236 					CFPreferencesSetAppValue(mref, data, kCFPreferencesCurrentApplication);
237 					CFRelease(data);
238 				}
239 
240 				CFRelease(sref);
241 			}
242 
243 			CFRelease(mref);
244 		}
245 	}
246 
247 	mref = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("Preferences_SaveFolder"));
248 	if (mref)
249 	{
250 		if (saveFolderPath)
251 		{
252 			CFPreferencesSetAppValue(mref, saveFolderPath, kCFPreferencesCurrentApplication);
253 			CFRelease(saveFolderPath);
254 		}
255 		else
256 			CFPreferencesSetAppValue(mref, NULL, kCFPreferencesCurrentApplication);
257 
258 		CFRelease(mref);
259 	}
260 
261 	sref = (CFStringRef) CFDictionaryGetValue(CFBundleGetInfoDictionary(CFBundleGetMainBundle()), CFSTR("CFBundleShortVersionString"));
262 	if (sref)
263 	{
264 		CFPreferencesSetAppValue(CFSTR("LastVersionUsed"), sref, kCFPreferencesCurrentApplication);
265 	}
266 
267 	CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
268 }
269 
LoadPrefs(void)270 void LoadPrefs (void)
271 {
272 	CFMutableStringRef	mref;
273 	CFStringRef			sref;
274 	CFDataRef			data;
275 
276 	for (unsigned int i = 0; i < kPrefListSize; i++)
277 	{
278 		mref = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("Preferences_"));
279 		if (mref)
280 		{
281 			sref = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *) &(prefList[i].itemName), sizeof(OSType), kCFStringEncodingMacRoman, false);
282 			if (sref)
283 			{
284 				CFStringAppend(mref, sref);
285 
286 				data = (CFDataRef) CFPreferencesCopyAppValue(mref, kCFPreferencesCurrentApplication);
287 				if (data)
288 				{
289 					if (CFDataGetLength(data) == prefList[i].size)
290 						CFDataGetBytes(data, CFRangeMake(0, prefList[i].size), (UInt8 *) prefList[i].itemPointer);
291 					CFRelease(data);
292 				}
293 
294 				CFRelease(sref);
295 			}
296 
297 			CFRelease(mref);
298 		}
299 	}
300 
301 	mref = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("Preferences_SaveFolder"));
302 	if (mref)
303 	{
304 		sref = (CFStringRef) CFPreferencesCopyAppValue(mref, kCFPreferencesCurrentApplication);
305 		if (sref)
306 			saveFolderPath = sref;
307 
308 		CFRelease(mref);
309 	}
310 
311 	sref = (CFStringRef) CFPreferencesCopyAppValue(CFSTR("LastVersionUsed"), kCFPreferencesCurrentApplication);
312 	if (!sref) {
313 		Settings.SoundInputRate = 31950;
314 		macSoundBuffer_ms = 80;
315 	}
316 	else CFRelease(sref);
317 }
318 
ConfigurePreferences(void)319 void ConfigurePreferences (void)
320 {
321 	OSStatus	err;
322 	IBNibRef	nibRef;
323 
324 	err = CreateNibReference(kMacS9XCFString, &nibRef);
325 	if (err == noErr)
326 	{
327 		WindowRef	tWindowRef;
328 		SInt32		oldVolume;
329 		uint32		oldPlaybackRate, oldInputRate, oldInterval, oldBufferSize;
330 		bool8		oldSynchronize, old16BitPlayback, oldStereo, oldReverseStereo, oldLagEnable;
331 
332 		oldSynchronize   = Settings.SoundSync;
333 		old16BitPlayback = Settings.SixteenBitSound;
334 		oldStereo        = Settings.Stereo;
335 		oldReverseStereo = Settings.ReverseStereo;
336 		oldPlaybackRate  = Settings.SoundPlaybackRate;
337 		oldInputRate     = Settings.SoundInputRate;
338 		oldInterval      = macSoundInterval_ms;
339 		oldBufferSize    = macSoundBuffer_ms;
340 		oldLagEnable     = macSoundLagEnable;
341 		oldVolume        = macSoundVolume;
342 
343 		if (cartOpen)
344 			DeinitGameWindow();
345 
346 		S9xGraphicsDeinit();
347 
348 		err = CreateWindowFromNib(nibRef, CFSTR("Preferences"), &tWindowRef);
349 		if (err == noErr)
350 		{
351 			EventHandlerUPP		tUPP, iUPP, aUPP, pUPP;
352 			EventHandlerRef		tRef, iRef, aRef, pRef;
353 			EventTypeSpec		tEvents[] = { { kEventClassControl, kEventControlHit          } },
354 								iEvents[] = { { kEventClassControl, kEventControlClick        } },
355 								aEvents[] = { { kEventClassControl, kEventControlClick        } },
356 								pEvents[] = { { kEventClassWindow,  kEventWindowClose         },
357 											  { kEventClassCommand, kEventCommandProcess      },
358 											  { kEventClassCommand, kEventCommandUpdateStatus } };
359 			ControlActionUPP	arrowsUPP, sliderUPP;
360 			HIViewRef			ctl, root;
361 			HIViewID			cid;
362 			MenuRef				menu;
363 			char				num[16];
364 
365 			root = HIViewGetRoot(tWindowRef);
366 
367 			cid.signature = 'tabs';
368 			cid.id = 128;
369 			HIViewFindByID(root, cid, &ctl);
370 			SetControl32BitValue(ctl, lastTabIndex);
371 			SelectTabPane(ctl, lastTabIndex);
372 			tUPP = NewEventHandlerUPP(TabEventHandler);
373 			err = InstallControlEventHandler(ctl, tUPP, GetEventTypeCount(tEvents), tEvents, 0, &tRef);
374 
375 			cid.signature = 'snd_';
376 			cid.id = iNibSInputRateText;
377 			HIViewFindByID(root, cid, &ctl);
378 			iUPP = NewEventHandlerUPP(InputRateTextEventHandler);
379 			err = InstallControlEventHandler(ctl, iUPP, GetEventTypeCount(iEvents), iEvents, 0, &iRef);
380 
381 			cid.signature = 'grap';
382 			cid.id = iNibGAspectRatioText;
383 			HIViewFindByID(root, cid, &ctl);
384 			aUPP = NewEventHandlerUPP(AspectRatioTextEventHandler);
385 			err = InstallControlEventHandler(ctl, aUPP, GetEventTypeCount(aEvents), aEvents, 0, &aRef);
386 
387 			pUPP = NewEventHandlerUPP(PreferencesEventHandler);
388 			err = InstallWindowEventHandler(tWindowRef, pUPP, GetEventTypeCount(pEvents), pEvents, (void *) tWindowRef, &pRef);
389 
390 			sliderUPP = NewControlActionUPP(InputRateSliderActionProc);
391 			arrowsUPP = NewControlActionUPP(LittleArrowsActionProc);
392 
393 			cid.signature = 'grap';
394 
395 			cid.id = iNibGFullScreen;
396 			HIViewFindByID(root, cid, &ctl);
397 			SetControl32BitValue(ctl, fullscreen);
398 
399 			cid.id = iNibGSwitchResolution;
400 			HIViewFindByID(root, cid, &ctl);
401 			SetControl32BitValue(ctl, autoRes);
402 
403 			cid.id = iNibGShowFrameRate;
404 			HIViewFindByID(root, cid, &ctl);
405 			SetControl32BitValue(ctl, Settings.DisplayFrameRate);
406 
407 			cid.id = iNibGTransparency;
408 			HIViewFindByID(root, cid, &ctl);
409 			SetControl32BitValue(ctl, Settings.Transparency);
410 
411 			cid.id = iNibGGL32bit;
412 			HIViewFindByID(root, cid, &ctl);
413 			SetControl32BitValue(ctl, gl32bit);
414 
415 			cid.id = iNibGGLStretch;
416 			HIViewFindByID(root, cid, &ctl);
417 			SetControl32BitValue(ctl, glstretch);
418 
419 			cid.id = iNibGVideoMode;
420 			HIViewFindByID(root, cid, &ctl);
421 			switch (videoMode)
422 			{
423 				case VIDEOMODE_BLOCKY:
424 					SetControl32BitValue(ctl, iOpenGLBlocky);
425 					break;
426 
427 				case VIDEOMODE_TV:
428 					SetControl32BitValue(ctl, iOpenGLTVMode);
429 					break;
430 
431 				case VIDEOMODE_SMOOTH:
432 					SetControl32BitValue(ctl, iOpenGLSmoothMode);
433 					break;
434 
435 				case VIDEOMODE_BLEND:
436 					SetControl32BitValue(ctl, iOpenGLBlendMode);
437 					break;
438 
439 				case VIDEOMODE_SUPEREAGLE:
440 					SetControl32BitValue(ctl, iOpenGLEagleMode);
441 					break;
442 
443 				case VIDEOMODE_2XSAI:
444 					SetControl32BitValue(ctl, iOpenGL2xSAIMode);
445 					break;
446 
447 				case VIDEOMODE_SUPER2XSAI:
448 					SetControl32BitValue(ctl, iOpenGLSuper2xSAIMode);
449 					break;
450 
451 				case VIDEOMODE_EPX:
452 					SetControl32BitValue(ctl, iOpenGLEPXMode);
453 					break;
454 
455 				case VIDEOMODE_HQ2X:
456 					SetControl32BitValue(ctl, iOpenGLHQ2xMode);
457 					break;
458 
459 				case VIDEOMODE_HQ3X:
460 					SetControl32BitValue(ctl, iOpenGLHQ3xMode);
461 					break;
462 
463 				case VIDEOMODE_HQ4X:
464 					SetControl32BitValue(ctl, iOpenGLHQ4xMode);
465 					break;
466 
467 				case VIDEOMODE_NTSC_C:
468 					SetControl32BitValue(ctl, iOpenGLNTSC_CMode);
469 					break;
470 
471 				case VIDEOMODE_NTSC_S:
472 					SetControl32BitValue(ctl, iOpenGLNTSC_SMode);
473 					break;
474 
475 				case VIDEOMODE_NTSC_R:
476 					SetControl32BitValue(ctl, iOpenGLNTSC_RMode);
477 					break;
478 
479 				case VIDEOMODE_NTSC_M:
480 					SetControl32BitValue(ctl, iOpenGLNTSC_MMode);
481 					break;
482 
483 				case VIDEOMODE_NTSC_TV_C:
484 					SetControl32BitValue(ctl, iOpenGLNTSC_TV_CMode);
485 					break;
486 
487 				case VIDEOMODE_NTSC_TV_S:
488 					SetControl32BitValue(ctl, iOpenGLNTSC_TV_SMode);
489 					break;
490 
491 				case VIDEOMODE_NTSC_TV_R:
492 					SetControl32BitValue(ctl, iOpenGLNTSC_TV_RMode);
493 					break;
494 
495 				case VIDEOMODE_NTSC_TV_M:
496 					SetControl32BitValue(ctl, iOpenGLNTSC_TV_MMode);
497 					break;
498 			}
499 
500 			cid.id = iNibGDirectMP;
501 			HIViewFindByID(root, cid, &ctl);
502 			SetControl32BitValue(ctl, multiprocessor);
503 
504 			cid.id = iNibGGLVSync;
505 			HIViewFindByID(root, cid, &ctl);
506 			SetControl32BitValue(ctl, vsync);
507 
508 			cid.id = iNibGDrawOverscan;
509 			HIViewFindByID(root, cid, &ctl);
510 			SetControl32BitValue(ctl, drawoverscan);
511 
512 			cid.id = iNibGScreenCurvature;
513 			HIViewFindByID(root, cid, &ctl);
514 			SetControl32BitValue(ctl, screencurvature);
515 
516 			cid.id = iNibGCurvatureWarp;
517 			HIViewFindByID(root, cid, &ctl);
518 			SetControl32BitValue(ctl, macCurvatureWarp);
519 			if (!screencurvature)
520 				DeactivateControl(ctl);
521 
522 			cid.id = iNibGAspectRatio;
523 			HIViewFindByID(root, cid, &ctl);
524 			SetControl32BitValue(ctl, macAspectRatio);
525 			if (!glstretch)
526 				DeactivateControl(ctl);
527 
528 			cid.id = iNibGCIFilterEnable;
529 			HIViewFindByID(root, cid, &ctl);
530 			SetControl32BitValue(ctl, ciFilterEnable);
531 			if (systemVersion < 0x1040)
532 				DisableControl(ctl);
533 
534 			if (systemVersion < 0x1040)
535 			{
536 				cid.id = iNibGCoreImageFilter;
537 				HIViewFindByID(root, cid, &ctl);
538 				DisableControl(ctl);
539 			}
540 
541 			cid.signature = 'snd_';
542 
543 			cid.id = iNibSSynchronize;
544 			HIViewFindByID(root, cid, &ctl);
545 			SetControl32BitValue(ctl, Settings.SoundSync);
546 
547 			cid.id = iNibS16BitPlayback;
548 			HIViewFindByID(root, cid, &ctl);
549 			SetControl32BitValue(ctl, Settings.SixteenBitSound);
550 			DeactivateControl(ctl);
551 
552 			cid.id = iNibSStereo;
553 			HIViewFindByID(root, cid, &ctl);
554 			SetControl32BitValue(ctl, Settings.Stereo);
555 			DeactivateControl(ctl);
556 
557 			cid.id = iNibSReverseStereo;
558 			HIViewFindByID(root, cid, &ctl);
559 			SetControl32BitValue(ctl, Settings.ReverseStereo);
560 			DeactivateControl(ctl);
561 
562 			cid.id = iNibSPlaybackRate;
563 			HIViewFindByID(root, cid, &ctl);
564 			switch (Settings.SoundPlaybackRate)
565 			{
566 				case 48000:
567 					SetControl32BitValue(ctl, 1);
568 					break;
569 
570 				case 44100:
571 					SetControl32BitValue(ctl, 2);
572 					break;
573 
574 				case 35000:
575 					SetControl32BitValue(ctl, 3);
576 					break;
577 
578 				case 32000:
579 					SetControl32BitValue(ctl, 4);
580 					break;
581 
582 				case 30000:
583 					SetControl32BitValue(ctl, 5);
584 					break;
585 
586 				case 22050:
587 					SetControl32BitValue(ctl, 6);
588 					break;
589 
590 				case 16000:
591 					SetControl32BitValue(ctl, 7);
592 					break;
593 
594 				case 11025:
595 					SetControl32BitValue(ctl, 8);
596 					break;
597 
598 				case 8000:
599 					SetControl32BitValue(ctl, 9);
600 					break;
601 			}
602 
603 			cid.id = iNibSInputRate;
604 			HIViewFindByID(root, cid, &ctl);
605 			SetControl32BitValue(ctl, Settings.SoundInputRate);
606 			SetControlAction(ctl, sliderUPP);
607 
608 			cid.id = iNibSInputRateText;
609 			HIViewFindByID(root, cid, &ctl);
610 			sprintf(num, "%d", Settings.SoundInputRate);
611 			SetStaticTextCStr(ctl, num, false);
612 
613 			cid.id = iNibSInterval;
614 			HIViewFindByID(root, cid, &ctl);
615 			switch (macSoundInterval_ms)
616 			{
617 				case 8:
618 					SetControl32BitValue(ctl, 1);
619 					break;
620 
621 				case 16:
622 					SetControl32BitValue(ctl, 2);
623 					break;
624 
625 				case 32:
626 					SetControl32BitValue(ctl, 3);
627 					break;
628 
629 				case 64:
630 					SetControl32BitValue(ctl, 4);
631 					break;
632 
633 				case 0:
634 				default:
635 					SetControl32BitValue(ctl, 6);
636 					break;
637 			}
638 
639 			cid.id = iNibSBufferSize;
640 			HIViewFindByID(root, cid, &ctl);
641 			SetControl32BitValue(ctl, macSoundBuffer_ms / 20);
642 
643 			cid.id = iNibSAllowLag;
644 			HIViewFindByID(root, cid, &ctl);
645 			SetControl32BitValue(ctl, macSoundLagEnable);
646 			DeactivateControl(ctl);
647 
648 			cid.id = iNibSVolume;
649 			HIViewFindByID(root, cid, &ctl);
650 			SetControl32BitValue(ctl, macSoundVolume);
651 
652 			cid.signature = 'othe';
653 
654 			cid.id = iNibOSaveFolder;
655 			HIViewFindByID(root, cid, &ctl);
656 			SetControl32BitValue(ctl, saveInROMFolder + 1);
657 			err = GetControlData(ctl, kControlMenuPart, kControlPopupButtonMenuRefTag, sizeof(MenuRef), &menu, NULL);
658 			if (saveFolderPath)
659 			{
660 				CFURLRef	url;
661 				CFStringRef	ref;
662 
663 				url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, saveFolderPath, kCFURLPOSIXPathStyle, true);
664 				ref = CFURLCopyLastPathComponent(url);
665 				err = SetMenuItemTextWithCFString(menu, iNibSaveFolderNameMenuItem, ref);
666 				CFRelease(ref);
667 				CFRelease(url);
668 				EnableMenuItem(menu, iNibSaveFolderNameMenuItem);
669 			}
670 			else
671 			{
672 				CFStringRef	ref;
673 
674 				ref = CFCopyLocalizedString(CFSTR("NoneSelected"), "NoneSelected");
675 				err = SetMenuItemTextWithCFString(menu, iNibSaveFolderNameMenuItem, ref);
676 				CFRelease(ref);
677 				DisableMenuItem(menu, iNibSaveFolderNameMenuItem);
678 			}
679 
680 			cid.id = iNibOAutoSaveInterval;
681 			HIViewFindByID(root, cid, &ctl);
682 			sprintf(num, "%d", Settings.AutoSaveDelay);
683 			SetEditTextCStr(ctl, num, false);
684 
685 			cid.signature = 'msc2';
686 
687 			cid.id = iNibMCPUCycles;
688 			HIViewFindByID(root, cid, &ctl);
689 			sprintf(num, "%" PRIi32, Settings.HDMATimingHack);
690 			SetEditTextCStr(ctl, num, false);
691 
692 			cid.id = iNibMTurboSkipArrows;
693 			HIViewFindByID(root, cid, &ctl);
694 			SetControl32BitValue(ctl, macFastForwardRate);
695 			SetControlAction(ctl, arrowsUPP);
696 
697 			cid.id = iNibMTurboSkipText;
698 			HIViewFindByID(root, cid, &ctl);
699 			sprintf(num, "%d", macFastForwardRate);
700 			SetStaticTextCStr(ctl, num, false);
701 
702 			cid.id = iNibMFrameSkip;
703 			HIViewFindByID(root, cid, &ctl);
704 			SetControl32BitValue(ctl, macFrameSkip + 2);
705 
706 			cid.id = iNibMAllowInvalidVRAMAccess;
707 			HIViewFindByID(root, cid, &ctl);
708 			SetControl32BitValue(ctl, !Settings.BlockInvalidVRAMAccessMaster);
709 
710 			cid.id = iNibMAllowSpecificGameHacks;
711 			HIViewFindByID(root, cid, &ctl);
712 			SetControl32BitValue(ctl, !Settings.DisableGameSpecificHacks);
713 
714 			cid.signature = 'osx_';
715 
716 			cid.id = iNibXStartOpenDialog;
717 			HIViewFindByID(root, cid, &ctl);
718 			SetControl32BitValue(ctl, startopendlog);
719 
720 			cid.id = iNibXShowTimeInFrz;
721 			HIViewFindByID(root, cid, &ctl);
722 			SetControl32BitValue(ctl, showtimeinfrz);
723 
724 			cid.id = iNibXMusicBoxMode;
725 			HIViewFindByID(root, cid, &ctl);
726 			SetControl32BitValue(ctl, musicboxmode);
727 
728 			cid.id = iNibXEnableToggle;
729 			HIViewFindByID(root, cid, &ctl);
730 			SetControl32BitValue(ctl, enabletoggle);
731 
732 			cid.id = iNibXSaveWindowPos;
733 			HIViewFindByID(root, cid, &ctl);
734 			SetControl32BitValue(ctl, savewindowpos);
735 
736 			cid.id = iNibXUseIPSPatch;
737 			HIViewFindByID(root, cid, &ctl);
738 			SetControl32BitValue(ctl, !Settings.NoPatch);
739 
740 			cid.id = iNibXOnScreenInfo;
741 			HIViewFindByID(root, cid, &ctl);
742 			SetControl32BitValue(ctl, onscreeninfo);
743 
744 			cid.id = iNibXInactiveMode;
745 			HIViewFindByID(root, cid, &ctl);
746 			SetControl32BitValue(ctl, inactiveMode);
747 
748 			cid.id = iNibXBSXBootup;
749 			HIViewFindByID(root, cid, &ctl);
750 			SetControl32BitValue(ctl, Settings.BSXBootup);
751 
752 			MoveWindowPosition(tWindowRef, kWindowPreferences, false);
753 			ShowWindow(tWindowRef);
754 			err = RunAppModalLoopForWindow(tWindowRef);
755 			HideWindow(tWindowRef);
756 			SaveWindowPosition(tWindowRef, kWindowPreferences);
757 
758 			cid.signature = 'grap';
759 
760 			cid.id = iNibGFullScreen;
761 			HIViewFindByID(root, cid, &ctl);
762 			fullscreen = GetControl32BitValue(ctl) ? true : false;
763 
764 			cid.id = iNibGSwitchResolution;
765 			HIViewFindByID(root, cid, &ctl);
766 			autoRes = GetControl32BitValue(ctl) ? true : false;
767 
768 			cid.id = iNibGShowFrameRate;
769 			HIViewFindByID(root, cid, &ctl);
770 			Settings.DisplayFrameRate = GetControl32BitValue(ctl) ? true : false;
771 
772 			cid.id = iNibGTransparency;
773 			HIViewFindByID(root, cid, &ctl);
774 			Settings.Transparency = GetControl32BitValue(ctl) ? true : false;
775 
776 			cid.id = iNibGGL32bit;
777 			HIViewFindByID(root, cid, &ctl);
778 			gl32bit = GetControl32BitValue(ctl) ? true : false;
779 
780 			cid.id = iNibGGLStretch;
781 			HIViewFindByID(root, cid, &ctl);
782 			glstretch = GetControl32BitValue(ctl) ? true : false;
783 
784 			cid.id = iNibGVideoMode;
785 			HIViewFindByID(root, cid, &ctl);
786 			switch (GetControl32BitValue(ctl))
787 			{
788 				case iOpenGLBlocky:
789 					drawingMethod = kDrawingOpenGL;
790 					videoMode = VIDEOMODE_BLOCKY;
791 					break;
792 
793 				case iOpenGLTVMode:
794 					drawingMethod = kDrawingBlitGL;
795 					videoMode = VIDEOMODE_TV;
796 					break;
797 
798 				case iOpenGLSmoothMode:
799 					drawingMethod = kDrawingOpenGL;
800 					videoMode = VIDEOMODE_SMOOTH;
801 					break;
802 
803 				case iOpenGLBlendMode:
804 					drawingMethod = kDrawingBlitGL;
805 					videoMode = VIDEOMODE_BLEND;
806 					break;
807 
808 				case iOpenGLEagleMode:
809 					drawingMethod = kDrawingBlitGL;
810 					videoMode = VIDEOMODE_SUPEREAGLE;
811 					break;
812 
813 				case iOpenGL2xSAIMode:
814 					drawingMethod = kDrawingBlitGL;
815 					videoMode = VIDEOMODE_2XSAI;
816 					break;
817 
818 				case iOpenGLSuper2xSAIMode:
819 					drawingMethod = kDrawingBlitGL;
820 					videoMode = VIDEOMODE_SUPER2XSAI;
821 					break;
822 
823 				case iOpenGLEPXMode:
824 					drawingMethod = kDrawingBlitGL;
825 					videoMode = VIDEOMODE_EPX;
826 					break;
827 
828 				case iOpenGLHQ2xMode:
829 					drawingMethod = kDrawingBlitGL;
830 					videoMode = VIDEOMODE_HQ2X;
831 					break;
832 
833 				case iOpenGLHQ3xMode:
834 					drawingMethod = kDrawingBlitGL;
835 					videoMode = VIDEOMODE_HQ3X;
836 					break;
837 
838 				case iOpenGLHQ4xMode:
839 					drawingMethod = kDrawingBlitGL;
840 					videoMode = VIDEOMODE_HQ4X;
841 					break;
842 
843 				case iOpenGLNTSC_CMode:
844 					drawingMethod = kDrawingBlitGL;
845 					videoMode = VIDEOMODE_NTSC_C;
846 					S9xBlitNTSCFilterSet(&snes_ntsc_composite);
847 					break;
848 
849 				case iOpenGLNTSC_SMode:
850 					drawingMethod = kDrawingBlitGL;
851 					videoMode = VIDEOMODE_NTSC_S;
852 					S9xBlitNTSCFilterSet(&snes_ntsc_svideo);
853 					break;
854 
855 				case iOpenGLNTSC_RMode:
856 					drawingMethod = kDrawingBlitGL;
857 					videoMode = VIDEOMODE_NTSC_R;
858 					S9xBlitNTSCFilterSet(&snes_ntsc_rgb);
859 					break;
860 
861 				case iOpenGLNTSC_MMode:
862 					drawingMethod = kDrawingBlitGL;
863 					videoMode = VIDEOMODE_NTSC_M;
864 					S9xBlitNTSCFilterSet(&snes_ntsc_monochrome);
865 					break;
866 
867 				case iOpenGLNTSC_TV_CMode:
868 					drawingMethod = kDrawingBlitGL;
869 					videoMode = VIDEOMODE_NTSC_TV_C;
870 					S9xBlitNTSCFilterSet(&snes_ntsc_composite);
871 					break;
872 
873 				case iOpenGLNTSC_TV_SMode:
874 					drawingMethod = kDrawingBlitGL;
875 					videoMode = VIDEOMODE_NTSC_TV_S;
876 					S9xBlitNTSCFilterSet(&snes_ntsc_svideo);
877 					break;
878 
879 				case iOpenGLNTSC_TV_RMode:
880 					drawingMethod = kDrawingBlitGL;
881 					videoMode = VIDEOMODE_NTSC_TV_R;
882 					S9xBlitNTSCFilterSet(&snes_ntsc_rgb);
883 					break;
884 
885 				case iOpenGLNTSC_TV_MMode:
886 					drawingMethod = kDrawingBlitGL;
887 					videoMode = VIDEOMODE_NTSC_TV_M;
888 					S9xBlitNTSCFilterSet(&snes_ntsc_monochrome);
889 					break;
890 			}
891 
892 			cid.id = iNibGDirectMP;
893 			HIViewFindByID(root, cid, &ctl);
894 			multiprocessor = GetControl32BitValue(ctl) ? true : false;
895 
896 			cid.id = iNibGGLVSync;
897 			HIViewFindByID(root, cid, &ctl);
898 			vsync = GetControl32BitValue(ctl) ? true : false;
899 
900 			cid.id = iNibGDrawOverscan;
901 			HIViewFindByID(root, cid, &ctl);
902 			drawoverscan = GetControl32BitValue(ctl) ? true : false;
903 
904 			cid.id = iNibGScreenCurvature;
905 			HIViewFindByID(root, cid, &ctl);
906 			screencurvature = GetControl32BitValue(ctl) ? true : false;
907 
908 			cid.id = iNibGCurvatureWarp;
909 			HIViewFindByID(root, cid, &ctl);
910 			macCurvatureWarp = GetControl32BitValue(ctl);
911 
912 			cid.id = iNibGAspectRatio;
913 			HIViewFindByID(root, cid, &ctl);
914 			macAspectRatio = GetControl32BitValue(ctl);
915 
916 			cid.id = iNibGCIFilterEnable;
917 			HIViewFindByID(root, cid, &ctl);
918 			ciFilterEnable = GetControl32BitValue(ctl) ? true : false;
919 
920 			cid.signature = 'snd_';
921 
922 			cid.id = iNibSSynchronize;
923 			HIViewFindByID(root, cid, &ctl);
924 			Settings.SoundSync = GetControl32BitValue(ctl) ? true : false;
925 
926 			cid.id = iNibS16BitPlayback;
927 			HIViewFindByID(root, cid, &ctl);
928 			Settings.SixteenBitSound = GetControl32BitValue(ctl) ? true : false;
929 
930 			cid.id = iNibSStereo;
931 			HIViewFindByID(root, cid, &ctl);
932 			Settings.Stereo = GetControl32BitValue(ctl) ? true : false;
933 
934 			cid.id = iNibSReverseStereo;
935 			HIViewFindByID(root, cid, &ctl);
936 			Settings.ReverseStereo = GetControl32BitValue(ctl) ? true : false;
937 
938 			cid.id = iNibSPlaybackRate;
939 			HIViewFindByID(root, cid, &ctl);
940 			switch (GetControl32BitValue(ctl))
941 			{
942 				case 1:
943 					Settings.SoundPlaybackRate = 48000;
944 					break;
945 
946 				case 2:
947 					Settings.SoundPlaybackRate = 44100;
948 					break;
949 
950 				case 3:
951 					Settings.SoundPlaybackRate = 35000;
952 					break;
953 
954 				case 4:
955 					Settings.SoundPlaybackRate = 32000;
956 					break;
957 
958 				case 5:
959 					Settings.SoundPlaybackRate = 30000;
960 					break;
961 
962 				case 6:
963 					Settings.SoundPlaybackRate = 22050;
964 					break;
965 
966 				case 7:
967 					Settings.SoundPlaybackRate = 16000;
968 					break;
969 
970 				case 8:
971 					Settings.SoundPlaybackRate = 11025;
972 					break;
973 
974 				case 9:
975 					Settings.SoundPlaybackRate = 8000;
976 					break;
977 			}
978 
979 			cid.id = iNibSInputRate;
980 			HIViewFindByID(root, cid, &ctl);
981 			Settings.SoundInputRate = GetControl32BitValue(ctl);
982 
983 			cid.id = iNibSInterval;
984 			HIViewFindByID(root, cid, &ctl);
985 			switch (GetControl32BitValue(ctl))
986 			{
987 				case 1:
988 					macSoundInterval_ms = 8;
989 					break;
990 
991 				case 2:
992 					macSoundInterval_ms = 16;
993 					break;
994 
995 				case 3:
996 					macSoundInterval_ms = 32;
997 					break;
998 
999 				case 4:
1000 					macSoundInterval_ms = 64;
1001 					break;
1002 
1003 				case 6:
1004 				default:
1005 					macSoundInterval_ms = 0;
1006 					break;
1007 			}
1008 
1009 			cid.id = iNibSBufferSize;
1010 			HIViewFindByID(root, cid, &ctl);
1011 			macSoundBuffer_ms = GetControl32BitValue(ctl) * 20;
1012 
1013 			cid.id = iNibSAllowLag;
1014 			HIViewFindByID(root, cid, &ctl);
1015 			macSoundLagEnable = GetControl32BitValue(ctl);
1016 
1017 			cid.id = iNibSVolume;
1018 			HIViewFindByID(root, cid, &ctl);
1019 			macSoundVolume = GetControl32BitValue(ctl);
1020 
1021 			cid.signature = 'othe';
1022 
1023 			cid.id = iNibOSaveFolder;
1024 			HIViewFindByID(root, cid, &ctl);
1025 			saveInROMFolder = GetControl32BitValue(ctl) - 1;
1026 
1027 			cid.id = iNibOAutoSaveInterval;
1028 			HIViewFindByID(root, cid, &ctl);
1029 			GetEditTextCStr(ctl, num);
1030 			Settings.AutoSaveDelay = atoi(num);
1031 
1032 			cid.signature = 'msc2';
1033 
1034 			cid.id = iNibMCPUCycles;
1035 			HIViewFindByID(root, cid, &ctl);
1036 			GetEditTextCStr(ctl, num);
1037 			Settings.HDMATimingHack = atoi(num);
1038 			if ((Settings.HDMATimingHack <= 0) || (Settings.HDMATimingHack >= 200))
1039 				Settings.HDMATimingHack = 100;
1040 
1041 			cid.id = iNibMTurboSkipArrows;
1042 			HIViewFindByID(root, cid, &ctl);
1043 			macFastForwardRate = GetControl32BitValue(ctl);
1044 
1045 			cid.id = iNibMFrameSkip;
1046 			HIViewFindByID(root, cid, &ctl);
1047 			macFrameSkip = GetControl32BitValue(ctl) - 2;
1048 
1049 			cid.id = iNibMAllowInvalidVRAMAccess;
1050 			HIViewFindByID(root, cid, &ctl);
1051 			Settings.BlockInvalidVRAMAccessMaster = GetControl32BitValue(ctl) ? false : true;
1052 
1053 			cid.id = iNibMAllowSpecificGameHacks;
1054 			HIViewFindByID(root, cid, &ctl);
1055 			Settings.DisableGameSpecificHacks = GetControl32BitValue(ctl) ? false : true;
1056 
1057 			cid.signature = 'osx_';
1058 
1059 			cid.id = iNibXStartOpenDialog;
1060 			HIViewFindByID(root, cid, &ctl);
1061 			startopendlog = GetControl32BitValue(ctl) ? true : false;
1062 
1063 			cid.id = iNibXShowTimeInFrz;
1064 			HIViewFindByID(root, cid, &ctl);
1065 			showtimeinfrz = GetControl32BitValue(ctl) ? true : false;
1066 
1067 			cid.id = iNibXMusicBoxMode;
1068 			HIViewFindByID(root, cid, &ctl);
1069 			musicboxmode = GetControl32BitValue(ctl);
1070 
1071 			cid.id = iNibXEnableToggle;
1072 			HIViewFindByID(root, cid, &ctl);
1073 			enabletoggle = GetControl32BitValue(ctl) ? true : false;
1074 
1075 			cid.id = iNibXSaveWindowPos;
1076 			HIViewFindByID(root, cid, &ctl);
1077 			savewindowpos = GetControl32BitValue(ctl) ? true : false;
1078 
1079 			cid.id = iNibXUseIPSPatch;
1080 			HIViewFindByID(root, cid, &ctl);
1081 			Settings.NoPatch = GetControl32BitValue(ctl) ? false : true;
1082 
1083 			cid.id = iNibXOnScreenInfo;
1084 			HIViewFindByID(root, cid, &ctl);
1085 			onscreeninfo = GetControl32BitValue(ctl) ? true : false;
1086 
1087 			cid.id = iNibXInactiveMode;
1088 			HIViewFindByID(root, cid, &ctl);
1089 			inactiveMode = GetControl32BitValue(ctl);
1090 
1091 			cid.id = iNibXBSXBootup;
1092 			HIViewFindByID(root, cid, &ctl);
1093 			Settings.BSXBootup = GetControl32BitValue(ctl) ? true : false;
1094 
1095 			DisposeControlActionUPP(arrowsUPP);
1096 			DisposeControlActionUPP(sliderUPP);
1097 
1098 			err = RemoveEventHandler(pRef);
1099 			DisposeEventHandlerUPP(pUPP);
1100 
1101 			err = RemoveEventHandler(aRef);
1102 			DisposeEventHandlerUPP(aUPP);
1103 
1104 			err = RemoveEventHandler(iRef);
1105 			DisposeEventHandlerUPP(iUPP);
1106 
1107 			err = RemoveEventHandler(tRef);
1108 			DisposeEventHandlerUPP(tUPP);
1109 
1110 			CFRelease(tWindowRef);
1111 		}
1112 
1113 		DisposeNibReference(nibRef);
1114 
1115 		S9xGraphicsInit();
1116 
1117 		if (((oldSynchronize   != Settings.SoundSync        ) ||
1118 			 (old16BitPlayback != Settings.SixteenBitSound  ) ||
1119 			 (oldStereo        != Settings.Stereo           ) ||
1120 			 (oldReverseStereo != Settings.ReverseStereo    ) ||
1121 			 (oldPlaybackRate  != Settings.SoundPlaybackRate) ||
1122 			 (oldInputRate     != Settings.SoundInputRate   ) ||
1123 			 (oldInterval      != macSoundInterval_ms       ) ||
1124 			 (oldBufferSize    != macSoundBuffer_ms         ) ||
1125 			 (oldLagEnable     != macSoundLagEnable         ) ||
1126 			 (oldVolume        != macSoundVolume            )) && cartOpen)
1127 			SNES9X_InitSound();
1128 
1129 		if (!fullscreen && cartOpen)
1130 		{
1131 			InitGameWindow();
1132 			ShowWindow(gWindow);
1133 		}
1134 
1135 		if (cartOpen)
1136 		{
1137 			FSRef	ref;
1138 
1139 			err = FSPathMakeRef((unsigned char *) Memory.ROMFilename, &ref, NULL);
1140 			if (err == noErr)
1141 				CheckSaveFolder(&ref);
1142 		}
1143 	}
1144 }
1145 
SelectTabPane(HIViewRef tabControl,SInt16 index)1146 static void SelectTabPane (HIViewRef tabControl, SInt16 index)
1147 {
1148 	HIViewRef	sup, userPane, selectedPane = NULL;
1149 	HIViewID	cid;
1150 
1151 	lastTabIndex = index;
1152 
1153 	sup = HIViewGetSuperview(tabControl);
1154 	cid.signature = 'tabs';
1155 
1156 	for (int i = 1; i < tabList[0] + 1; i++)
1157 	{
1158 		cid.id = tabList[i];
1159 		HIViewFindByID(sup, cid, &userPane);
1160 
1161 		if (i == index)
1162 			selectedPane = userPane;
1163 		else
1164 			HIViewSetVisible(userPane, false);
1165 	}
1166 
1167 	if (selectedPane != NULL)
1168 		HIViewSetVisible(selectedPane, true);
1169 
1170 	HIViewSetNeedsDisplay(tabControl, true);
1171 }
1172 
InputRateSliderActionProc(HIViewRef slider,HIViewPartCode partCode)1173 static pascal void InputRateSliderActionProc (HIViewRef slider, HIViewPartCode partCode)
1174 {
1175 	HIViewRef	ctl;
1176 	HIViewID	cid;
1177 	char		num[10];
1178 
1179 	cid.signature = 'snd_';
1180 	cid.id = iNibSInputRateText;
1181 	HIViewFindByID(HIViewGetSuperview(slider), cid, &ctl);
1182 
1183 	sprintf(num, "%ld", GetControl32BitValue(slider));
1184 	SetStaticTextCStr(ctl, num, true);
1185 }
1186 
LittleArrowsActionProc(HIViewRef arrows,HIViewPartCode partCode)1187 static pascal void LittleArrowsActionProc (HIViewRef arrows, HIViewPartCode partCode)
1188 {
1189 	HIViewRef	ctl;
1190 	HIViewID	cid = { 'msc2', iNibMTurboSkipText };
1191 	char		num[8];
1192 
1193 	if (partCode == kControlUpButtonPart)
1194 		SetControl32BitValue(arrows, GetControl32BitValue(arrows) + 1);
1195 	else
1196 	if (partCode == kControlDownButtonPart)
1197 		SetControl32BitValue(arrows, GetControl32BitValue(arrows) - 1);
1198 
1199 	HIViewFindByID(HIViewGetSuperview(arrows), cid, &ctl);
1200 	sprintf(num, "%ld", GetControl32BitValue(arrows));
1201 	SetStaticTextCStr(ctl, num, true);
1202 }
1203 
InputRateTextEventHandler(EventHandlerCallRef inHandlerRef,EventRef inEvent,void * inUserData)1204 static pascal OSStatus InputRateTextEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
1205 {
1206 	OSStatus	err, result = eventNotHandledErr;
1207 	HIViewRef	ctl, slider;
1208 	HIViewID	cid;
1209 	SInt32		value;
1210 	char		num[10];
1211 
1212 	err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &ctl);
1213 	if (err == noErr)
1214 	{
1215 		cid.signature = 'snd_';
1216 		cid.id = iNibSInputRate;
1217 		HIViewFindByID(HIViewGetSuperview(ctl), cid, &slider);
1218 		value = GetControl32BitValue(slider);
1219 
1220 		value /= 50;
1221 		value *= 50;
1222 		if (value > 33000)
1223 			value = 33000;
1224 		if (value < 31000)
1225 			value = 31000;
1226 
1227 		SetControl32BitValue(slider, value);
1228 		sprintf(num, "%ld", value);
1229 		SetEditTextCStr(ctl, num, true);
1230 
1231 		result = noErr;
1232 	}
1233 
1234 	return (result);
1235 }
1236 
AspectRatioTextEventHandler(EventHandlerCallRef inHandlerRef,EventRef inEvent,void * inUserData)1237 static pascal OSStatus AspectRatioTextEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
1238 {
1239 	OSStatus	err, result = eventNotHandledErr;
1240 	HIViewRef	ctl, slider;
1241 	HIViewID	cid;
1242 	float		w, h, v;
1243 	int			iw, ih;
1244 
1245 	err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &ctl);
1246 	if (err == noErr)
1247 	{
1248 		cid.signature = 'grap';
1249 		cid.id = iNibGAspectRatio;
1250 		HIViewFindByID(HIViewGetSuperview(ctl), cid, &slider);
1251 
1252 		GetGameDisplay(&iw, &ih);
1253 		w = (float) iw;
1254 		h = (float) ih;
1255 
1256 		v = (float) SNES_WIDTH / (float) SNES_HEIGHT * h;
1257 		macAspectRatio = (int) (((4.0f / 3.0f) * h - v) / (w - v) * 10000.0f);
1258 
1259 		SetControl32BitValue(slider, macAspectRatio);
1260 
1261 		result = noErr;
1262 	}
1263 
1264 	return (result);
1265 }
1266 
TabEventHandler(EventHandlerCallRef inHandlerRef,EventRef inEvent,void * inUserData)1267 static pascal OSStatus TabEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
1268 {
1269 	OSStatus	err, result = eventNotHandledErr;
1270 	HIViewRef	ctl;
1271 	HIViewID	cid;
1272 	SInt32		value;
1273 
1274 	err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &ctl);
1275 	if (err == noErr)
1276 	{
1277 		GetControlID(ctl, &cid);
1278 		value = GetControl32BitValue(ctl);
1279 
1280 		if ((cid.id == 128) && (value != lastTabIndex))
1281 		{
1282 			SelectTabPane(ctl, value);
1283 			result = noErr;
1284 		}
1285 	}
1286 
1287 	return (result);
1288 }
1289 
PreferencesEventHandler(EventHandlerCallRef inHandlerRef,EventRef inEvent,void * inUserData)1290 static pascal OSStatus PreferencesEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
1291 {
1292 	OSStatus	err, result = eventNotHandledErr;
1293 	WindowRef	tWindowRef = (WindowRef) inUserData;
1294 
1295 	switch (GetEventClass(inEvent))
1296 	{
1297 		case kEventClassWindow:
1298 		{
1299 			switch (GetEventKind(inEvent))
1300 			{
1301 				case kEventWindowClose:
1302 				{
1303 					QuitAppModalLoopForWindow(tWindowRef);
1304 					result = noErr;
1305 					break;
1306 				}
1307 			}
1308 
1309 			break;
1310 		}
1311 
1312 		case kEventClassCommand:
1313 		{
1314 			switch (GetEventKind(inEvent))
1315 			{
1316 				HICommand	tHICommand;
1317 
1318 				case kEventCommandUpdateStatus:
1319 				{
1320 					err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
1321 					if (err == noErr && tHICommand.commandID == 'clos')
1322 					{
1323 						UpdateMenuCommandStatus(true);
1324 						result = noErr;
1325 					}
1326 
1327 					break;
1328 				}
1329 
1330 				case kEventCommandProcess:
1331 				{
1332 					HIViewRef	ctl, root;
1333 					HIViewID	cid;
1334 					SInt32		value;
1335 					FSRef		ref;
1336 					bool8		r;
1337 
1338 					root = HIViewGetRoot(tWindowRef);
1339 
1340 					err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
1341 					if (err == noErr)
1342 					{
1343 						switch (tHICommand.commandID)
1344 						{
1345 							case 'S_EF':
1346 							{
1347 								HideWindow(tWindowRef);
1348 								ConfigureSoundEffects();
1349 								ShowWindow(tWindowRef);
1350 
1351 								result = noErr;
1352 								break;
1353 							}
1354 
1355 							case 'G_FL':
1356 							{
1357 								if (systemVersion >= 0x1040)
1358 								{
1359 									HideWindow(tWindowRef);
1360 									ConfigureCoreImageFilter();
1361 									ShowWindow(tWindowRef);
1362 								}
1363 
1364 								result = noErr;
1365 								break;
1366 							}
1367 
1368 							case 'G__7':
1369 							{
1370 								cid.signature = 'grap';
1371 								cid.id = iNibGGLStretch;
1372 								HIViewFindByID(root, cid, &ctl);
1373 								value = GetControl32BitValue(ctl);
1374 
1375 								cid.id = iNibGAspectRatio;
1376 								HIViewFindByID(root, cid, &ctl);
1377 								if (value)
1378 									ActivateControl(ctl);
1379 								else
1380 									DeactivateControl(ctl);
1381 
1382 								result = noErr;
1383 								break;
1384 							}
1385 
1386 							case 'G_13':
1387 							{
1388 								cid.signature = 'grap';
1389 								cid.id = iNibGScreenCurvature;
1390 								HIViewFindByID(root, cid, &ctl);
1391 								value = GetControl32BitValue(ctl);
1392 
1393 								cid.id = iNibGCurvatureWarp;
1394 								HIViewFindByID(root, cid, &ctl);
1395 								if (value)
1396 									ActivateControl(ctl);
1397 								else
1398 									DeactivateControl(ctl);
1399 
1400 								result = noErr;
1401 								break;
1402 							}
1403 
1404 							case 'S__3':
1405 							{
1406 								cid.signature = 'snd_';
1407 								cid.id = iNibSStereo;
1408 								HIViewFindByID(root, cid, &ctl);
1409 								value = GetControl32BitValue(ctl);
1410 
1411 								cid.id = iNibSReverseStereo;
1412 								HIViewFindByID(root, cid, &ctl);
1413 								if (value)
1414 									ActivateControl(ctl);
1415 								else
1416 									DeactivateControl(ctl);
1417 
1418 								result = noErr;
1419 								break;
1420 							}
1421 
1422 							case 'F_FL':
1423 							{
1424 								UInt32	modifierkey;
1425 
1426 								err = GetEventParameter(inEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifierkey);
1427 								if (err == noErr)
1428 								{
1429 									if (modifierkey & optionKey)
1430 									{
1431 										CFStringRef	str;
1432 										MenuRef		menu;
1433 
1434 										str = CFCopyLocalizedString(CFSTR("NoneSelected"), "NoneSelected");
1435 
1436 										cid.signature = 'othe';
1437 										cid.id = iNibOSaveFolder;
1438 										HIViewFindByID(root, cid, &ctl);
1439 										SetControl32BitValue(ctl, 3);
1440 										err = GetControlData(ctl, kControlMenuPart, kControlPopupButtonMenuRefTag, sizeof(MenuRef), &menu, NULL);
1441 										err = SetMenuItemTextWithCFString(menu, iNibSaveFolderNameMenuItem, str);
1442 										DisableMenuItem(menu, iNibSaveFolderNameMenuItem);
1443 										HIViewSetNeedsDisplay(ctl, true);
1444 
1445 										CFRelease(str);
1446 
1447 										if (saveFolderPath)
1448 											CFRelease(saveFolderPath);
1449 										saveFolderPath = NULL;
1450 									}
1451 									else
1452 										r = NavBeginChooseFolderSheet(tWindowRef);
1453 								}
1454 
1455 								result = noErr;
1456 								break;
1457 							}
1458 
1459 							case 'NvDn':
1460 							{
1461 								r = NavEndChooseFolderSheet(&ref);
1462 								if (r)
1463 								{
1464 									CFStringRef	str;
1465 									CFURLRef	url;
1466 									MenuRef		menu;
1467 
1468 									url = CFURLCreateFromFSRef(kCFAllocatorDefault, &ref);
1469 									str = CFURLCopyLastPathComponent(url);
1470 
1471 									cid.signature = 'othe';
1472 									cid.id = iNibOSaveFolder;
1473 									HIViewFindByID(root, cid, &ctl);
1474 									SetControl32BitValue(ctl, iNibSaveFolderNameMenuItem);
1475 									err = GetControlData(ctl, kControlMenuPart, kControlPopupButtonMenuRefTag, sizeof(MenuRef), &menu, NULL);
1476 									err = SetMenuItemTextWithCFString(menu, iNibSaveFolderNameMenuItem, str);
1477 									EnableMenuItem(menu, iNibSaveFolderNameMenuItem);
1478 									HIViewSetNeedsDisplay(ctl, true);
1479 
1480 									CFRelease(str);
1481 
1482 									str = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
1483 									if (saveFolderPath)
1484 										CFRelease(saveFolderPath);
1485 									saveFolderPath = str;
1486 
1487 									CFRelease(url);
1488 								}
1489 
1490 								result = noErr;
1491 								break;
1492 							}
1493 						}
1494 					}
1495 
1496 					break;
1497 				}
1498 			}
1499 
1500 			break;
1501 		}
1502 	}
1503 
1504 	return (result);
1505 }
1506 
ConfigureExtraOptions(void)1507 void ConfigureExtraOptions (void)
1508 {
1509 	OSStatus	err;
1510 	IBNibRef	nibRef;
1511 
1512 	err = CreateNibReference(kMacS9XCFString, &nibRef);
1513 	if (err == noErr)
1514 	{
1515 		WindowRef	tWindowRef;
1516 
1517 		err = CreateWindowFromNib(nibRef, CFSTR("ExtraOptions"), &tWindowRef);
1518 		if (err == noErr)
1519 		{
1520 			EventHandlerRef	eref;
1521 			EventHandlerUPP	eventUPP;
1522 			EventTypeSpec	windowEvents[] = { { kEventClassWindow,  kEventWindowClose         },
1523 											   { kEventClassCommand, kEventCommandUpdateStatus } };
1524 			HIViewRef		ctl, root;
1525 			HIViewID		cid;
1526 
1527 			root = HIViewGetRoot(tWindowRef);
1528 			cid.id = 0;
1529 
1530 			cid.signature = 'BMrk';
1531 			HIViewFindByID(root, cid, &ctl);
1532 			SetControl32BitValue(ctl, extraOptions.benchmark);
1533 
1534 			cid.signature = 'NoTR';
1535 			HIViewFindByID(root, cid, &ctl);
1536 			SetControl32BitValue(ctl, extraOptions.glForceNoTextureRectangle);
1537 
1538 			cid.signature = 'CSAp';
1539 			HIViewFindByID(root, cid, &ctl);
1540 			SetControl32BitValue(ctl, extraOptions.glUseClientStrageApple);
1541 
1542 			cid.signature = 'AGPT';
1543 			HIViewFindByID(root, cid, &ctl);
1544 			SetControl32BitValue(ctl, extraOptions.glUseTexturePriority);
1545 
1546 			cid.signature = 'Hint';
1547 			HIViewFindByID(root, cid, &ctl);
1548 			SetControl32BitValue(ctl, extraOptions.glStorageHint);
1549 
1550 			eventUPP = NewEventHandlerUPP(DefaultEventHandler);
1551 			err = InstallWindowEventHandler(tWindowRef, eventUPP, GetEventTypeCount(windowEvents), windowEvents, (void *) tWindowRef, &eref);
1552 
1553 			MoveWindowPosition(tWindowRef, kWindowExtra, false);
1554 			ShowWindow(tWindowRef);
1555 			err = RunAppModalLoopForWindow(tWindowRef);
1556 			HideWindow(tWindowRef);
1557 			SaveWindowPosition(tWindowRef, kWindowExtra);
1558 
1559 			cid.signature = 'BMrk';
1560 			HIViewFindByID(root, cid, &ctl);
1561 			extraOptions.benchmark = GetControl32BitValue(ctl) ? true : false;
1562 
1563 			cid.signature = 'NoTR';
1564 			HIViewFindByID(root, cid, &ctl);
1565 			extraOptions.glForceNoTextureRectangle = GetControl32BitValue(ctl) ? true : false;
1566 
1567 			cid.signature = 'CSAp';
1568 			HIViewFindByID(root, cid, &ctl);
1569 			extraOptions.glUseClientStrageApple = GetControl32BitValue(ctl) ? true : false;
1570 
1571 			cid.signature = 'AGPT';
1572 			HIViewFindByID(root, cid, &ctl);
1573 			extraOptions.glUseTexturePriority = GetControl32BitValue(ctl) ? true : false;
1574 
1575 			cid.signature = 'Hint';
1576 			HIViewFindByID(root, cid, &ctl);
1577 			extraOptions.glStorageHint = GetControl32BitValue(ctl);
1578 
1579 			err = RemoveEventHandler(eref);
1580 			DisposeEventHandlerUPP(eventUPP);
1581 
1582 			CFRelease(tWindowRef);
1583 		}
1584 
1585 		DisposeNibReference(nibRef);
1586 	}
1587 }
1588