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 
24 #include "mac-prefix.h"
25 #include "mac-audio.h"
26 #include "mac-joypad.h"
27 #include "mac-keyboard.h"
28 #include "mac-os.h"
29 #include "mac-render.h"
30 #include "mac-stringtools.h"
31 #include "mac-dialog.h"
32 
33 int	autofireLastTabIndex = 1;
34 
35 static int	tabList[] = { 2, 257, 258 };
36 
37 static void RomInfoCopyToClipboard (void);
38 static void RomInfoBuildInfoText (char *);
39 static void AutofireSetAllIconImages (int, HIViewRef);
40 static void AutofireSetIconImages (int, HIViewRef);
41 static void AutofireReadAllSettings (int, HIViewRef);
42 static void AutofireReadSetting (int, uint16, HIViewRef);
43 static void AutofireWriteAllSettings (int, HIViewRef);
44 static void AutofireWriteSetting (int, uint16 *, HIViewRef);
45 static void AutofireSelectTabPane (HIViewRef, SInt16);
46 static OSStatus UpdateTextControlView (HIViewRef);
47 static pascal void AutofireSliderActionProc (HIViewRef, HIViewPartCode);
48 static pascal OSStatus RomInfoEventHandler (EventHandlerCallRef, EventRef, void *);
49 static pascal OSStatus AutofireTabEventHandler (EventHandlerCallRef, EventRef, void *);
50 static pascal OSStatus AutofireWindowEventHandler (EventHandlerCallRef, EventRef, void *);
51 
52 #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
53 extern "C" FMFont FMGetFontFromATSFontRef (ATSFontRef iFont);
54 #endif
55 
56 
UpdateTextControlView(HIViewRef control)57 static OSStatus UpdateTextControlView (HIViewRef control)
58 {
59 	OSStatus			err;
60 	WindowAttributes	attr;
61 
62 	err = GetWindowAttributes(GetControlOwner(control), &attr);
63 	if (err == noErr)
64 	{
65 		if (attr & kWindowCompositingAttribute)
66 			err = HIViewSetNeedsDisplay(control, true);
67 		else
68 			Draw1Control(control);
69 	}
70 
71 	return (err);
72 }
73 
SetStaticTextCStr(HIViewRef control,char * text,Boolean draw)74 OSStatus SetStaticTextCStr (HIViewRef control, char *text, Boolean draw)
75 {
76 	OSStatus	err;
77 
78 	if (!control || !text)
79 		return (paramErr);
80 
81 	err = SetControlData(control, 0, kControlStaticTextTextTag, strlen(text), text);
82 	if ((err == noErr) && draw)
83 		err = UpdateTextControlView(control);
84 
85 	return (err);
86 }
87 
SetStaticTextCFString(HIViewRef control,CFStringRef text,Boolean draw)88 OSStatus SetStaticTextCFString (HIViewRef control, CFStringRef text, Boolean draw)
89 {
90 	OSStatus	err;
91 
92 	if (!control || !text)
93 		return (paramErr);
94 
95 	err = SetControlData(control, 0, kControlStaticTextCFStringTag, sizeof(CFStringRef), &text);
96 	if ((err == noErr) && draw)
97 		err = UpdateTextControlView(control);
98 
99 	return (err);
100 }
101 
SetStaticTextTrunc(HIViewRef control,TruncCode mode,Boolean draw)102 OSStatus SetStaticTextTrunc (HIViewRef control, TruncCode mode, Boolean draw)
103 {
104 	OSStatus	err;
105 	TruncCode	trunc;
106 	Boolean		multiline;
107 
108 	if (!control)
109 		return (paramErr);
110 
111 	trunc = mode;
112 	multiline = false;
113 
114 	err = SetControlData(control, 0, kControlStaticTextIsMultilineTag, sizeof(Boolean), &multiline);
115 	if (err == noErr)
116 	{
117 		err = SetControlData(control, 0, kControlStaticTextTruncTag, sizeof(TruncCode), &trunc);
118 		if ((err == noErr) && draw)
119 			err = UpdateTextControlView(control);
120 	}
121 
122 	return (err);
123 }
124 
GetEditTextCStr(HIViewRef control,char * text)125 OSStatus GetEditTextCStr (HIViewRef control, char *text)
126 {
127 	OSStatus	err;
128 	Size		actualSize;
129 
130 	if (!control || !text)
131 		return (paramErr);
132 
133 	err = GetControlData(control, 0, kControlEditTextTextTag, 255, text, &actualSize);
134 	if (err == noErr)
135 		text[actualSize] = 0;
136 
137 	return (err);
138 }
139 
SetEditTextCStr(HIViewRef control,char * text,Boolean draw)140 OSStatus SetEditTextCStr (HIViewRef control, char *text, Boolean draw)
141 {
142 	OSStatus	err;
143 
144 	if (!control || !text)
145 		return (paramErr);
146 
147 	err = SetControlData(control, 0, kControlEditTextTextTag, strlen(text), text);
148 	if ((err == noErr) && draw)
149 		err = UpdateTextControlView(control);
150 
151 	return (err);
152 }
153 
CopyEditTextCFString(HIViewRef control,CFStringRef * text)154 OSStatus CopyEditTextCFString (HIViewRef control, CFStringRef *text)
155 {
156 	OSStatus	err;
157 	Size		actualSize;
158 
159 	if (!control || !text)
160 		return (paramErr);
161 
162 	err = GetControlData(control, 0, kControlEditTextCFStringTag, sizeof(CFStringRef), text, &actualSize);
163 
164 	return (err);
165 }
166 
SetEditTextCFString(HIViewRef control,CFStringRef text,Boolean draw)167 OSStatus SetEditTextCFString (HIViewRef control, CFStringRef text, Boolean draw)
168 {
169 	OSStatus	err;
170 
171 	if (!control || !text)
172 		return (paramErr);
173 
174 	err = SetControlData(control, 0, kControlEditTextCFStringTag, sizeof(CFStringRef), &text);
175 	if ((err == noErr) && draw)
176 		err = UpdateTextControlView(control);
177 
178 	return (err);
179 }
180 
SetEditTextSelection(HIViewRef control,SInt16 selStart,SInt16 selEnd)181 OSStatus SetEditTextSelection (HIViewRef control, SInt16 selStart, SInt16 selEnd)
182 {
183 	OSStatus					err;
184 	ControlEditTextSelectionRec	selection;
185 
186 	if (!control)
187 		return (paramErr);
188 
189 	selection.selStart = selStart;
190 	selection.selEnd   = selEnd;
191 
192 	err = SetControlData(control, 0, kControlEditTextSelectionTag, sizeof(selection), &selection);
193 	if (err == noErr)
194 		err = UpdateTextControlView(control);
195 
196 	return (err);
197 }
198 
StartCarbonModalDialog(void)199 void StartCarbonModalDialog (void)
200 {
201 	HiliteMenu(0);
202 	if (gWindow)
203 		HideWindow(gWindow);
204 }
205 
FinishCarbonModalDialog(void)206 void FinishCarbonModalDialog (void)
207 {
208 	if (gWindow)
209 		ShowWindow(gWindow);
210 }
211 
MoveWindowPosition(WindowRef window,int which,Boolean resize)212 void MoveWindowPosition (WindowRef window, int which, Boolean resize)
213 {
214 	if (savewindowpos)
215 	{
216 		MoveWindow(window, windowPos[which].h, windowPos[which].v, false);
217 
218 		if (resize)
219 		{
220 			if ((windowSize[which].width > 0) && (windowSize[which].height > 0))
221 				SizeWindow(window, (short) windowSize[which].width, (short) windowSize[which].height, false);
222 		}
223 	}
224 	else
225 		RepositionWindow(window, NULL, kWindowAlertPositionOnMainScreen);
226 }
227 
SaveWindowPosition(WindowRef window,int which)228 void SaveWindowPosition (WindowRef window, int which)
229 {
230 	Rect	rct;
231 
232 	GetWindowBounds(window, kWindowContentRgn, &rct);
233 	windowPos[which].h = rct.left;
234 	windowPos[which].v = rct.top;
235 	windowSize[which].width  = (float) (rct.right  - rct.left);
236 	windowSize[which].height = (float) (rct.bottom - rct.top );
237 }
238 
AppearanceAlert(AlertType type,int stringID1,int stringID2)239 void AppearanceAlert (AlertType type, int stringID1, int stringID2)
240 {
241 	OSStatus		err;
242 	DialogRef		dialog;
243 	DialogItemIndex	outItemHit;
244 	CFStringRef		key1, key2, mes1, mes2;
245 	char			label1[32], label2[32];
246 
247 	sprintf(label1, "AlertMes_%02d", stringID1);
248 	sprintf(label2, "AlertMes_%02d", stringID2);
249 
250 	key1 = CFStringCreateWithCString(kCFAllocatorDefault, label1, CFStringGetSystemEncoding());
251 	key2 = CFStringCreateWithCString(kCFAllocatorDefault, label2, CFStringGetSystemEncoding());
252 
253 	if (key1) mes1 = CFCopyLocalizedString(key1, "mes1");	else mes1 = NULL;
254 	if (key2) mes2 = CFCopyLocalizedString(key2, "mes2");	else mes2 = NULL;
255 
256 	PlayAlertSound();
257 
258 	err = CreateStandardAlert(type, mes1, mes2, NULL, &dialog);
259 	err = RunStandardAlert(dialog, NULL, &outItemHit);
260 
261 	if (key1) CFRelease(key1);
262 	if (key2) CFRelease(key2);
263 	if (mes1) CFRelease(mes1);
264 	if (mes2) CFRelease(mes2);
265 }
266 
AboutDialog(void)267 void AboutDialog (void)
268 {
269 	OSStatus	err;
270 	IBNibRef	nibRef;
271 
272 	err = CreateNibReference(kMacS9XCFString, &nibRef);
273 	if (err == noErr)
274 	{
275 		WindowRef	tWindowRef;
276 
277 		err = CreateWindowFromNib(nibRef, CFSTR("About"), &tWindowRef);
278 		if (err == noErr)
279 		{
280 			EventHandlerRef		eref;
281 			EventHandlerUPP		eventUPP;
282 			EventTypeSpec		windowEvents[] = { { kEventClassWindow,  kEventWindowClose         },
283 												   { kEventClassCommand, kEventCommandUpdateStatus } };
284 			ControlFontStyleRec	frec;
285 			HIViewRef			ctl, root;
286 			HIViewID			cid;
287 			char				text[32];
288 
289 			err = ChangeWindowAttributes(tWindowRef, kWindowNoAttributes, kWindowInWindowMenuAttribute);
290 
291 			if (systemVersion >= 0x1040)
292 				frec.font = FMGetFontFromATSFontRef(ATSFontFindFromName(CFSTR("Lucida Grande"), kATSOptionFlagsDefault));
293 		#ifdef MAC_PANTHER_SUPPORT
294 			else
295 				frec.font = kThemeSystemFont;
296 		#endif
297 			frec.just = teCenter;
298 
299 			root = HIViewGetRoot(tWindowRef);
300 			cid.id = 0;
301 
302 			cid.signature = 'VERS';
303 			HIViewFindByID(root, cid, &ctl);
304 			sprintf(text, "Version %s (%s)", VERSION, MAC_VERSION);
305 			SetStaticTextCStr(ctl, text, false);
306 			frec.flags = kControlUseFontMask | kControlUseSizeMask | kControlUseJustMask;
307 			frec.size  = 10;
308 			err = SetControlFontStyle(ctl, &frec);
309 
310 			cid.signature = 'NAME';
311 			HIViewFindByID(root, cid, &ctl);
312 			frec.flags = kControlUseFontMask | kControlUseSizeMask | kControlUseFaceMask | kControlUseJustMask;
313 			frec.size  = 14;
314 			frec.style = 1;
315 			err = SetControlFontStyle(ctl, &frec);
316 
317 			eventUPP = NewEventHandlerUPP(DefaultEventHandler);
318 			err = InstallWindowEventHandler(tWindowRef, eventUPP, GetEventTypeCount(windowEvents), windowEvents, (void *) tWindowRef, &eref);
319 
320 			MoveWindowPosition(tWindowRef, kWindowAbout, false);
321 			ShowWindow(tWindowRef);
322 			err = RunAppModalLoopForWindow(tWindowRef);
323 			HideWindow(tWindowRef);
324 			SaveWindowPosition(tWindowRef, kWindowAbout);
325 
326 			err = RemoveEventHandler(eref);
327 			DisposeEventHandlerUPP(eventUPP);
328 
329 			CFRelease(tWindowRef);
330 		}
331 
332 		DisposeNibReference(nibRef);
333 	}
334 }
335 
DefaultEventHandler(EventHandlerCallRef inHandlerRef,EventRef inEvent,void * inUserData)336 pascal OSStatus DefaultEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
337 {
338 	OSStatus	err, result = eventNotHandledErr;
339 	WindowRef	tWindowRef = (WindowRef) inUserData;
340 
341 	switch (GetEventClass(inEvent))
342 	{
343 		case kEventClassWindow:
344 			switch (GetEventKind(inEvent))
345 			{
346 				case kEventWindowClose:
347 					QuitAppModalLoopForWindow(tWindowRef);
348 					result = noErr;
349 			}
350 
351 			break;
352 
353 		case kEventClassCommand:
354 			switch (GetEventKind(inEvent))
355 			{
356 				case kEventCommandUpdateStatus:
357 					HICommand	tHICommand;
358 
359 					err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
360 					if (err == noErr && tHICommand.commandID == 'clos')
361 					{
362 						UpdateMenuCommandStatus(true);
363 						result = noErr;
364 					}
365 			}
366 
367 			break;
368 	}
369 
370 	return (result);
371 }
372 
ConfigureAutofire(void)373 void ConfigureAutofire (void)
374 {
375 	OSStatus	err;
376 	IBNibRef	nibRef;
377 
378 	err = CreateNibReference(kMacS9XCFString, &nibRef);
379 	if (err == noErr)
380 	{
381 		WindowRef	tWindowRef;
382 
383 		err = CreateWindowFromNib(nibRef, CFSTR("AutoFire"), &tWindowRef);
384 		if (err == noErr)
385 		{
386 			EventHandlerRef		wRef, tRef;
387 			EventHandlerUPP		wUPP, tUPP;
388 			EventTypeSpec		wEvent[] = { { kEventClassWindow,  kEventWindowClose         },
389 											 { kEventClassCommand, kEventCommandProcess      },
390 											 { kEventClassCommand, kEventCommandUpdateStatus } },
391 								tEvent[] = { { kEventClassControl, kEventControlHit          } };
392 			ControlActionUPP	actionUPP;
393 			HIViewRef			ctl, root;
394 			HIViewID			cid;
395 
396 			root = HIViewGetRoot(tWindowRef);
397 
398 			wUPP = NewEventHandlerUPP(AutofireWindowEventHandler);
399 			err = InstallWindowEventHandler(tWindowRef, wUPP, GetEventTypeCount(wEvent), wEvent, (void *) tWindowRef, &wRef);
400 
401 			cid.signature = 'Ftab';
402 			cid.id = 256;
403 			HIViewFindByID(root, cid, &ctl);
404 			SetControl32BitValue(ctl, autofireLastTabIndex);
405 			AutofireSelectTabPane(ctl, autofireLastTabIndex);
406 			tUPP = NewEventHandlerUPP(AutofireTabEventHandler);
407 			err = InstallControlEventHandler(ctl, tUPP, GetEventTypeCount(tEvent), tEvent, 0, &tRef);
408 
409 			actionUPP = NewControlActionUPP(AutofireSliderActionProc);
410 
411 			for (int player = 0; player < 2; player++)
412 			{
413 				AutofireSetAllIconImages(player + 1, root);
414 				AutofireReadAllSettings(player + 1, root);
415 
416 				cid.id = player + 1;
417 				cid.signature = 'Slid';
418 				HIViewFindByID(root, cid, &ctl);
419 				SetControlAction(ctl, actionUPP);
420 			}
421 
422 			MoveWindowPosition(tWindowRef, kWindowAutoFire, false);
423 			ShowWindow(tWindowRef);
424 			err = RunAppModalLoopForWindow(tWindowRef);
425 			HideWindow(tWindowRef);
426 			SaveWindowPosition(tWindowRef, kWindowAutoFire);
427 
428 			for (int player = 0; player < 2; player++)
429 				AutofireWriteAllSettings(player + 1, root);
430 
431 			autofire = (autofireRec[0].buttonMask || autofireRec[1].buttonMask) ? true : false;
432 
433 			err = RemoveEventHandler(tRef);
434 			DisposeEventHandlerUPP(tUPP);
435 
436 			err = RemoveEventHandler(wRef);
437 			DisposeEventHandlerUPP(wUPP);
438 
439 			DisposeControlActionUPP(actionUPP);
440 
441 			CFRelease(tWindowRef);
442 		}
443 
444 		DisposeNibReference(nibRef);
445 	}
446 }
447 
AutofireSetAllIconImages(int player,HIViewRef parent)448 static void AutofireSetAllIconImages (int player, HIViewRef parent)
449 {
450 	AutofireSetIconImages(player * 1,    parent);
451 	AutofireSetIconImages(player * 11,   parent);
452 	AutofireSetIconImages(player * 111,  parent);
453 	AutofireSetIconImages(player * 1111, parent);
454 }
455 
AutofireSetIconImages(int sig,HIViewRef parent)456 static void AutofireSetIconImages (int sig, HIViewRef parent)
457 {
458 	OSStatus					err;
459 	ControlButtonContentInfo	info;
460 	HIViewRef					ctl;
461 	HIViewID					cid;
462 	int							ofs;
463 
464 	cid.id = sig;
465 	ofs = macPadIconIndex + ((sig % 2) ? 0 : 12);
466 
467 	if (systemVersion >= 0x1040)
468 	{
469 		info.contentType = kControlContentCGImageRef;
470 
471 		cid.signature = 'AChk';
472 		HIViewFindByID(parent, cid, &ctl);
473 		info.u.imageRef = macIconImage[7 + ofs];
474 		err = SetBevelButtonContentInfo(ctl, &info);
475 
476 		cid.signature = 'BChk';
477 		HIViewFindByID(parent, cid, &ctl);
478 		info.u.imageRef = macIconImage[5 + ofs];
479 		err = SetBevelButtonContentInfo(ctl, &info);
480 
481 		cid.signature = 'XChk';
482 		HIViewFindByID(parent, cid, &ctl);
483 		info.u.imageRef = macIconImage[6 + ofs];
484 		err = SetBevelButtonContentInfo(ctl, &info);
485 
486 		cid.signature = 'YChk';
487 		HIViewFindByID(parent, cid, &ctl);
488 		info.u.imageRef = macIconImage[4 + ofs];
489 		err = SetBevelButtonContentInfo(ctl, &info);
490 
491 		cid.signature = 'LChk';
492 		HIViewFindByID(parent, cid, &ctl);
493 		info.u.imageRef = macIconImage[8 + ofs];
494 		err = SetBevelButtonContentInfo(ctl, &info);
495 
496 		cid.signature = 'RChk';
497 		HIViewFindByID(parent, cid, &ctl);
498 		info.u.imageRef = macIconImage[9 + ofs];
499 		err = SetBevelButtonContentInfo(ctl, &info);
500 
501 		cid.signature = 'Up  ';
502 		HIViewFindByID(parent, cid, &ctl);
503 		info.u.imageRef = macIconImage[0 + ofs];
504 		err = SetBevelButtonContentInfo(ctl, &info);
505 
506 		cid.signature = 'Down';
507 		HIViewFindByID(parent, cid, &ctl);
508 		info.u.imageRef = macIconImage[1 + ofs];
509 		err = SetBevelButtonContentInfo(ctl, &info);
510 
511 		cid.signature = 'Left';
512 		HIViewFindByID(parent, cid, &ctl);
513 		info.u.imageRef = macIconImage[2 + ofs];
514 		err = SetBevelButtonContentInfo(ctl, &info);
515 
516 		cid.signature = 'Righ';
517 		HIViewFindByID(parent, cid, &ctl);
518 		info.u.imageRef = macIconImage[3 + ofs];
519 		err = SetBevelButtonContentInfo(ctl, &info);
520 
521 		cid.signature = 'Star';
522 		HIViewFindByID(parent, cid, &ctl);
523 		info.u.imageRef = macIconImage[10 + ofs];
524 		err = SetBevelButtonContentInfo(ctl, &info);
525 
526 		cid.signature = 'Sele';
527 		HIViewFindByID(parent, cid, &ctl);
528 		info.u.imageRef = macIconImage[11 + ofs];
529 		err = SetBevelButtonContentInfo(ctl, &info);
530 	}
531 #ifdef MAC_PANTHER_SUPPORT
532 	else
533 	{
534 		info.contentType = kControlContentIconRef;
535 
536 		cid.signature = 'AChk';
537 		HIViewFindByID(parent, cid, &ctl);
538 		info.u.iconRef = macIconRef[7 + ofs];
539 		err = SetBevelButtonContentInfo(ctl, &info);
540 
541 		cid.signature = 'BChk';
542 		HIViewFindByID(parent, cid, &ctl);
543 		info.u.iconRef = macIconRef[5 + ofs];
544 		err = SetBevelButtonContentInfo(ctl, &info);
545 
546 		cid.signature = 'XChk';
547 		HIViewFindByID(parent, cid, &ctl);
548 		info.u.iconRef = macIconRef[6 + ofs];
549 		err = SetBevelButtonContentInfo(ctl, &info);
550 
551 		cid.signature = 'YChk';
552 		HIViewFindByID(parent, cid, &ctl);
553 		info.u.iconRef = macIconRef[4 + ofs];
554 		err = SetBevelButtonContentInfo(ctl, &info);
555 
556 		cid.signature = 'LChk';
557 		HIViewFindByID(parent, cid, &ctl);
558 		info.u.iconRef = macIconRef[8 + ofs];
559 		err = SetBevelButtonContentInfo(ctl, &info);
560 
561 		cid.signature = 'RChk';
562 		HIViewFindByID(parent, cid, &ctl);
563 		info.u.iconRef = macIconRef[9 + ofs];
564 		err = SetBevelButtonContentInfo(ctl, &info);
565 
566 		cid.signature = 'Up  ';
567 		HIViewFindByID(parent, cid, &ctl);
568 		info.u.iconRef = macIconRef[0 + ofs];
569 		err = SetBevelButtonContentInfo(ctl, &info);
570 
571 		cid.signature = 'Down';
572 		HIViewFindByID(parent, cid, &ctl);
573 		info.u.iconRef = macIconRef[1 + ofs];
574 		err = SetBevelButtonContentInfo(ctl, &info);
575 
576 		cid.signature = 'Left';
577 		HIViewFindByID(parent, cid, &ctl);
578 		info.u.iconRef = macIconRef[2 + ofs];
579 		err = SetBevelButtonContentInfo(ctl, &info);
580 
581 		cid.signature = 'Righ';
582 		HIViewFindByID(parent, cid, &ctl);
583 		info.u.iconRef = macIconRef[3 + ofs];
584 		err = SetBevelButtonContentInfo(ctl, &info);
585 
586 		cid.signature = 'Star';
587 		HIViewFindByID(parent, cid, &ctl);
588 		info.u.iconRef = macIconRef[10 + ofs];
589 		err = SetBevelButtonContentInfo(ctl, &info);
590 
591 		cid.signature = 'Sele';
592 		HIViewFindByID(parent, cid, &ctl);
593 		info.u.iconRef = macIconRef[11 + ofs];
594 		err = SetBevelButtonContentInfo(ctl, &info);
595 	}
596 #endif
597 }
598 
AutofireReadAllSettings(int player,HIViewRef parent)599 static void AutofireReadAllSettings (int player, HIViewRef parent)
600 {
601 	HIViewRef	ctl;
602 	HIViewID	cid;
603 	char		num[10];
604 
605 	AutofireReadSetting(player * 1,    autofireRec[player - 1].buttonMask, parent);
606 	AutofireReadSetting(player * 11,   autofireRec[player - 1].toggleMask, parent);
607 	AutofireReadSetting(player * 111,  autofireRec[player - 1].tcMask,     parent);
608 	AutofireReadSetting(player * 1111, autofireRec[player - 1].invertMask, parent);
609 
610 	cid.id = player;
611 
612 	cid.signature = 'Num_';
613 	HIViewFindByID(parent, cid, &ctl);
614 	sprintf(num, "%ld", autofireRec[player - 1].frequency);
615 	SetStaticTextCStr(ctl, num, false);
616 
617 	cid.signature = 'Slid';
618 	HIViewFindByID(parent, cid, &ctl);
619 	SetControl32BitValue(ctl, autofireRec[player - 1].frequency);
620 }
621 
AutofireReadSetting(int sig,uint16 target,HIViewRef parent)622 static void AutofireReadSetting (int sig, uint16 target, HIViewRef parent)
623 {
624 	HIViewRef	ctl;
625 	HIViewID	cid;
626 
627 	cid.id = sig;
628 
629 	cid.signature = 'AChk';
630 	HIViewFindByID(parent, cid, &ctl);
631 	SetControl32BitValue(ctl, (target & 0x0080) ? 1 : 0);
632 
633 	cid.signature = 'BChk';
634 	HIViewFindByID(parent, cid, &ctl);
635 	SetControl32BitValue(ctl, (target & 0x8000) ? 1 : 0);
636 
637 	cid.signature = 'XChk';
638 	HIViewFindByID(parent, cid, &ctl);
639 	SetControl32BitValue(ctl, (target & 0x0040) ? 1 : 0);
640 
641 	cid.signature = 'YChk';
642 	HIViewFindByID(parent, cid, &ctl);
643 	SetControl32BitValue(ctl, (target & 0x4000) ? 1 : 0);
644 
645 	cid.signature = 'LChk';
646 	HIViewFindByID(parent, cid, &ctl);
647 	SetControl32BitValue(ctl, (target & 0x0020) ? 1 : 0);
648 
649 	cid.signature = 'RChk';
650 	HIViewFindByID(parent, cid, &ctl);
651 	SetControl32BitValue(ctl, (target & 0x0010) ? 1 : 0);
652 
653 	cid.signature = 'Up  ';
654 	HIViewFindByID(parent, cid, &ctl);
655 	SetControl32BitValue(ctl, (target & 0x0800) ? 1 : 0);
656 
657 	cid.signature = 'Down';
658 	HIViewFindByID(parent, cid, &ctl);
659 	SetControl32BitValue(ctl, (target & 0x0400) ? 1 : 0);
660 
661 	cid.signature = 'Left';
662 	HIViewFindByID(parent, cid, &ctl);
663 	SetControl32BitValue(ctl, (target & 0x0200) ? 1 : 0);
664 
665 	cid.signature = 'Righ';
666 	HIViewFindByID(parent, cid, &ctl);
667 	SetControl32BitValue(ctl, (target & 0x0100) ? 1 : 0);
668 
669 	cid.signature = 'Star';
670 	HIViewFindByID(parent, cid, &ctl);
671 	SetControl32BitValue(ctl, (target & 0x1000) ? 1 : 0);
672 
673 	cid.signature = 'Sele';
674 	HIViewFindByID(parent, cid, &ctl);
675 	SetControl32BitValue(ctl, (target & 0x2000) ? 1 : 0);
676 }
677 
AutofireWriteAllSettings(int player,HIViewRef parent)678 static void AutofireWriteAllSettings (int player, HIViewRef parent)
679 {
680 	HIViewRef	ctl;
681 	HIViewID	cid;
682 
683 	AutofireWriteSetting(player * 1,    &(autofireRec[player - 1].buttonMask), parent);
684 	AutofireWriteSetting(player * 11,   &(autofireRec[player - 1].toggleMask), parent);
685 	AutofireWriteSetting(player * 111,  &(autofireRec[player - 1].tcMask),     parent);
686 	AutofireWriteSetting(player * 1111, &(autofireRec[player - 1].invertMask), parent);
687 
688 	cid.id = player;
689 	cid.signature = 'Slid';
690 	HIViewFindByID(parent, cid, &ctl);
691 	autofireRec[player - 1].frequency = GetControl32BitValue(ctl);
692 }
693 
AutofireWriteSetting(int sig,uint16 * target,HIViewRef parent)694 static void AutofireWriteSetting (int sig, uint16 *target, HIViewRef parent)
695 {
696 	HIViewRef	ctl;
697 	HIViewID	cid;
698 
699 	cid.id = sig;
700 	*target = 0x0000;
701 
702 	cid.signature = 'AChk';
703 	HIViewFindByID(parent, cid, &ctl);
704 	if (GetControl32BitValue(ctl))
705 		(*target) |= 0x0080;
706 
707 	cid.signature = 'BChk';
708 	HIViewFindByID(parent, cid, &ctl);
709 	if (GetControl32BitValue(ctl))
710 		(*target) |= 0x8000;
711 
712 	cid.signature = 'XChk';
713 	HIViewFindByID(parent, cid, &ctl);
714 	if (GetControl32BitValue(ctl))
715 		(*target) |= 0x0040;
716 
717 	cid.signature = 'YChk';
718 	HIViewFindByID(parent, cid, &ctl);
719 	if (GetControl32BitValue(ctl))
720 		(*target) |= 0x4000;
721 
722 	cid.signature = 'LChk';
723 	HIViewFindByID(parent, cid, &ctl);
724 	if (GetControl32BitValue(ctl))
725 		(*target) |= 0x0020;
726 
727 	cid.signature = 'RChk';
728 	HIViewFindByID(parent, cid, &ctl);
729 	if (GetControl32BitValue(ctl))
730 		(*target) |= 0x0010;
731 
732 	cid.signature = 'Up  ';
733 	HIViewFindByID(parent, cid, &ctl);
734 	if (GetControl32BitValue(ctl))
735 		(*target) |= 0x0800;
736 
737 	cid.signature = 'Down';
738 	HIViewFindByID(parent, cid, &ctl);
739 	if (GetControl32BitValue(ctl))
740 		(*target) |= 0x0400;
741 
742 	cid.signature = 'Left';
743 	HIViewFindByID(parent, cid, &ctl);
744 	if (GetControl32BitValue(ctl))
745 		(*target) |= 0x0200;
746 
747 	cid.signature = 'Righ';
748 	HIViewFindByID(parent, cid, &ctl);
749 	if (GetControl32BitValue(ctl))
750 		(*target) |= 0x0100;
751 
752 	cid.signature = 'Star';
753 	HIViewFindByID(parent, cid, &ctl);
754 	if (GetControl32BitValue(ctl))
755 		(*target) |= 0x1000;
756 
757 	cid.signature = 'Sele';
758 	HIViewFindByID(parent, cid, &ctl);
759 	if (GetControl32BitValue(ctl))
760 		(*target) |= 0x2000;
761 }
762 
AutofireSelectTabPane(HIViewRef tabControl,SInt16 index)763 static void AutofireSelectTabPane (HIViewRef tabControl, SInt16 index)
764 {
765 	HIViewRef	sup, userPane, selectedPane = NULL;
766 	HIViewID	cid;
767 
768 	autofireLastTabIndex = index;
769 
770 	sup = HIViewGetSuperview(tabControl);
771 	cid.signature = 'Ftab';
772 
773 	for (int i = 1; i < tabList[0] + 1; i++)
774 	{
775 		cid.id = tabList[i];
776 		HIViewFindByID(sup, cid, &userPane);
777 
778 		if (i == index)
779 			selectedPane = userPane;
780 		else
781 			HIViewSetVisible(userPane, false);
782 	}
783 
784 	if (selectedPane != NULL)
785 		HIViewSetVisible(selectedPane, true);
786 
787 	HIViewSetNeedsDisplay(tabControl, true);
788 }
789 
AutofireTabEventHandler(EventHandlerCallRef inHandlerRef,EventRef inEvent,void * inUserData)790 static pascal OSStatus AutofireTabEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
791 {
792 	OSStatus	err, result = eventNotHandledErr;
793 	HIViewRef	ctl;
794 	HIViewID	cid;
795 	SInt32		value;
796 
797 	err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &ctl);
798 	if (err == noErr)
799 	{
800 		GetControlID(ctl, &cid);
801 		value = GetControl32BitValue(ctl);
802 
803 		if ((cid.id == 256) && (value != autofireLastTabIndex))
804 		{
805 			AutofireSelectTabPane(ctl, value);
806 			result = noErr;
807 		}
808 	}
809 
810 	return (result);
811 }
812 
AutofireWindowEventHandler(EventHandlerCallRef inHandlerRef,EventRef inEvent,void * inUserData)813 static pascal OSStatus AutofireWindowEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
814 {
815 	OSStatus	err, result = eventNotHandledErr;
816 	WindowRef	tWindowRef = (WindowRef) inUserData;
817 
818 	switch (GetEventClass(inEvent))
819 	{
820 		case kEventClassWindow:
821 			switch (GetEventKind(inEvent))
822 			{
823 				case kEventWindowClose:
824 					QuitAppModalLoopForWindow(tWindowRef);
825 					result = noErr;
826 			}
827 
828 			break;
829 
830 		case kEventClassCommand:
831 			switch (GetEventKind(inEvent))
832 			{
833 				HICommand	tHICommand;
834 
835 				case kEventCommandUpdateStatus:
836 					err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
837 					if (err == noErr && tHICommand.commandID == 'clos')
838 					{
839 						UpdateMenuCommandStatus(true);
840 						result = noErr;
841 					}
842 
843 					break;
844 
845 				case kEventCommandProcess:
846 					HIViewRef	root;
847 					int			player = -1;
848 
849 					root = HIViewGetRoot(tWindowRef);
850 
851 					err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
852 					if (err == noErr)
853 					{
854 						switch (tHICommand.commandID)
855 						{
856 							case 'DEF1':
857 								player = 0;
858 								break;
859 
860 							case 'DEF2':
861 								player = 1;
862 								break;
863 						}
864 
865 						if (player != -1)
866 						{
867 							autofireRec[player].buttonMask = 0x0000;
868 							autofireRec[player].toggleMask = 0xFFF0;
869 							autofireRec[player].tcMask     = 0x0000;
870 							autofireRec[player].invertMask = 0x0000;
871 							autofireRec[player].frequency  = 10;
872 							AutofireReadAllSettings(player + 1, root);
873 
874 							result = noErr;
875 						}
876 					}
877 			}
878 	}
879 
880 	return (result);
881 }
882 
AutofireSliderActionProc(HIViewRef slider,HIViewPartCode partCode)883 static pascal void AutofireSliderActionProc (HIViewRef slider, HIViewPartCode partCode)
884 {
885 	HIViewRef	ctl;
886 	HIViewID	cid;
887 	char		num[10];
888 
889 	GetControlID(slider, &cid);
890 	cid.signature = 'Num_';
891 	HIViewFindByID(HIViewGetSuperview(slider), cid, &ctl);
892 
893 	sprintf(num, "%ld", GetControl32BitValue(slider));
894 	SetStaticTextCStr(ctl, num, true);
895 }
896 
RomInfoDialog(void)897 void RomInfoDialog (void)
898 {
899 	OSStatus	err;
900 	IBNibRef	nibRef;
901 
902 	if (!cartOpen)
903 		return;
904 
905 	err = CreateNibReference(kMacS9XCFString, &nibRef);
906 	if (err == noErr)
907 	{
908 		WindowRef	tWindowRef;
909 
910 		err = CreateWindowFromNib(nibRef, CFSTR("RomInfo"), &tWindowRef);
911 		if (err == noErr)
912 		{
913 			EventHandlerRef	eref;
914 			EventHandlerUPP	eventUPP;
915 			EventTypeSpec	windowEvents[] = { { kEventClassWindow,  kEventWindowClose         },
916 											   { kEventClassCommand, kEventCommandProcess      },
917 											   { kEventClassCommand, kEventCommandUpdateStatus } };
918 			CFStringRef		sref;
919 			HIViewRef		ctl, root;
920 			HIViewID		cid;
921 			char			text[256];
922 
923 			eventUPP = NewEventHandlerUPP(RomInfoEventHandler);
924 			err = InstallWindowEventHandler(tWindowRef, eventUPP, GetEventTypeCount(windowEvents), windowEvents, (void *) tWindowRef, &eref);
925 
926 			root = HIViewGetRoot(tWindowRef);
927 			cid.id = 0;
928 
929 			cid.signature = 'Name';	// Cart Name
930 			HIViewFindByID(root, cid, &ctl);
931 
932 			strcpy(text, Memory.RawROMName);
933 			sref = CopyFixNameStrings(text, Memory.ROMRegion);
934 			if (!sref)
935 				SetStaticTextCFString(ctl, CFSTR("unknown"), false);
936 			else
937 			{
938 				SetStaticTextCFString(ctl, sref, false);
939 				CFRelease(sref);
940 			}
941 
942 			cid.signature = 'Code';	// Game Code
943 			HIViewFindByID(root, cid, &ctl);
944 			sprintf(text, "%s", Memory.ROMId);
945 			SetStaticTextCStr(ctl, text, false);
946 
947 			cid.signature = 'Cont';	// Contents
948 			HIViewFindByID(root, cid, &ctl);
949 			sprintf(text, "%s", Memory.KartContents());
950 			SetStaticTextCStr(ctl, text, false);
951 
952 			cid.signature = 'Map ';	// ROM Map
953 			HIViewFindByID(root, cid, &ctl);
954 			sprintf(text, "%s", Memory.MapType());
955 			SetStaticTextCStr(ctl, text, false);
956 
957 			cid.signature = 'Spee';	// ROM Speed
958 			HIViewFindByID(root, cid, &ctl);
959 			sprintf(text, "0x%02X (%s)", Memory.ROMSpeed, ((Memory.ROMSpeed & 0x10) != 0) ? "FastROM" : "SlowROM");
960 			SetStaticTextCStr(ctl, text, false);
961 
962 			cid.signature = 'Type';	// ROM Type
963 			HIViewFindByID(root, cid, &ctl);
964 			sprintf(text, "0x%02X", Memory.ROMType);
965 			SetStaticTextCStr(ctl, text, false);
966 
967 			cid.signature = 'SizC';	// Actual ROM Size
968 			HIViewFindByID(root, cid, &ctl);
969 			sprintf(text, "%dMbits", Memory.CalculatedSize / 0x20000);
970 			SetStaticTextCStr(ctl, text, false);
971 
972 			cid.signature = 'SizH';	// ROM Size written in info block
973 			HIViewFindByID(root, cid, &ctl);
974 			sprintf(text, "%s", Memory.Size());
975 			SetStaticTextCStr(ctl, text, false);
976 
977 			cid.signature = 'SRAM';	// SRAM Size
978 			HIViewFindByID(root, cid, &ctl);
979 			sprintf(text, "%s", Memory.StaticRAMSize());
980 			SetStaticTextCStr(ctl, text, false);
981 
982 			cid.signature = 'SumC';	// Actual checksum
983 			HIViewFindByID(root, cid, &ctl);
984 			sprintf(text, "0x%04X", Memory.CalculatedChecksum);
985 			SetStaticTextCStr(ctl, text, false);
986 
987 			cid.signature = 'SumH';	// Checksum written in info block
988 			HIViewFindByID(root, cid, &ctl);
989 			sprintf(text, "0x%04X", Memory.ROMChecksum);
990 			SetStaticTextCStr(ctl, text, false);
991 
992 			cid.signature = 'ComH';	// Checksum complement written in info block : SumH + ComH = 0xFFFF
993 			HIViewFindByID(root, cid, &ctl);
994 			sprintf(text, "0x%04X", Memory.ROMComplementChecksum);
995 			SetStaticTextCStr(ctl, text, false);
996 
997 			cid.signature = 'Outp';	// Video output (NTSC or PAL)
998 			HIViewFindByID(root, cid, &ctl);
999 			sprintf(text, "%s", (Memory.ROMRegion > 12 || Memory.ROMRegion < 2) ? "NTSC 60Hz" : "PAL 50Hz");
1000 			SetStaticTextCStr(ctl, text, false);
1001 
1002 			cid.signature = 'Vers';	// Revision
1003 			HIViewFindByID(root, cid, &ctl);
1004 			sprintf(text, "%s", Memory.Revision());
1005 			SetStaticTextCStr(ctl, text, false);
1006 
1007 			cid.signature = 'Lice';	// Licensee
1008 			HIViewFindByID(root, cid, &ctl);
1009 			sprintf(text, "%s", Memory.PublishingCompany());
1010 			SetStaticTextCStr(ctl, text, false);
1011 
1012 			cid.signature = 'Regi';	// Region
1013 			HIViewFindByID(root, cid, &ctl);
1014 			sprintf(text, "%s", Memory.Country());
1015 			SetStaticTextCStr(ctl, text, false);
1016 
1017 			cid.signature = 'CRC ';	// CRC32
1018 			HIViewFindByID(root, cid, &ctl);
1019 			sprintf(text, "0x%08X", Memory.ROMCRC32);
1020 			SetStaticTextCStr(ctl, text, false);
1021 
1022 			MoveWindowPosition(tWindowRef, kWindowRomInfo, false);
1023 			ShowWindow(tWindowRef);
1024 			err = RunAppModalLoopForWindow(tWindowRef);
1025 			HideWindow(tWindowRef);
1026 			SaveWindowPosition(tWindowRef, kWindowRomInfo);
1027 
1028 			err = RemoveEventHandler(eref);
1029 			DisposeEventHandlerUPP(eventUPP);
1030 
1031 			CFRelease(tWindowRef);
1032 		}
1033 
1034 		DisposeNibReference(nibRef);
1035 	}
1036 }
1037 
RomInfoCopyToClipboard(void)1038 static void RomInfoCopyToClipboard (void)
1039 {
1040 	OSStatus			err;
1041 	PasteboardRef		clipboard;
1042 	PasteboardSyncFlags	sync;
1043 	CFDataRef			cfdata;
1044 	char				text[1024];
1045 
1046 	RomInfoBuildInfoText(text);
1047 
1048 	err = PasteboardCreate(kPasteboardClipboard, &clipboard);
1049 	if (err == noErr)
1050 	{
1051 		err = PasteboardClear(clipboard);
1052 		if (err == noErr)
1053 		{
1054 			sync = PasteboardSynchronize(clipboard);
1055 			if (!(sync & kPasteboardModified) && (sync & kPasteboardClientIsOwner))
1056 			{
1057 				cfdata = CFDataCreate(kCFAllocatorDefault, (UInt8 *) text, (CFIndex) strlen(text));
1058 				if (cfdata)
1059 				{
1060 					err = PasteboardPutItemFlavor(clipboard, (PasteboardItemID) 1, CFSTR("com.apple.traditional-mac-plain-text"), cfdata, 0);
1061 					CFRelease(cfdata);
1062 				}
1063 			}
1064 		}
1065 
1066 		CFRelease(clipboard);
1067 	}
1068 }
1069 
RomInfoBuildInfoText(char * romtext)1070 static void RomInfoBuildInfoText (char *romtext)
1071 {
1072 	char	s1[256], s2[1024];
1073 
1074 	sprintf(s1, "Snes9x version: %s\nMac port version: %s, ", VERSION, MAC_VERSION);
1075 #ifdef __BIG_ENDIAN__
1076 	strcat(s1, "PowerPC\n\n");
1077 #else
1078 	strcat(s1, "Intel\n\n");
1079 #endif
1080 	Memory.MakeRomInfoText(s2);
1081 	sprintf(romtext, "%s%s", s1, s2);
1082 }
1083 
RomInfoEventHandler(EventHandlerCallRef inHandlerRef,EventRef inEvent,void * inUserData)1084 static pascal OSStatus RomInfoEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
1085 {
1086 	OSStatus	err, result = eventNotHandledErr;
1087 	WindowRef	tWindowRef = (WindowRef) inUserData;
1088 
1089 	switch (GetEventClass(inEvent))
1090 	{
1091 		case kEventClassWindow:
1092 			switch (GetEventKind(inEvent))
1093 			{
1094 				case kEventWindowClose:
1095 					QuitAppModalLoopForWindow(tWindowRef);
1096 					result = noErr;
1097 			}
1098 
1099 			break;
1100 
1101 		case kEventClassCommand:
1102 			switch (GetEventKind(inEvent))
1103 			{
1104 				HICommand	tHICommand;
1105 
1106 				case kEventCommandUpdateStatus:
1107 					err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
1108 					if (err == noErr && tHICommand.commandID == 'clos')
1109 					{
1110 						UpdateMenuCommandStatus(true);
1111 						result = noErr;
1112 					}
1113 
1114 					break;
1115 
1116 				case kEventCommandProcess:
1117 					err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
1118 					if (err == noErr)
1119 					{
1120 						switch (tHICommand.commandID)
1121 						{
1122 							case 'Clip':
1123 								RomInfoCopyToClipboard();
1124 								result = noErr;
1125 						}
1126 					}
1127 			}
1128 	}
1129 
1130 	return (result);
1131 }
1132 
RegisterHelpBook(void)1133 void RegisterHelpBook (void)
1134 {
1135 	OSStatus	err;
1136 	CFBundleRef	bundleRef;
1137 	CFURLRef	bundleURL;
1138 	FSRef		fref;
1139 
1140 	bundleRef = CFBundleGetMainBundle();
1141 	if (bundleRef)
1142 	{
1143 		bundleURL = CFBundleCopyBundleURL(bundleRef);
1144 		if (bundleURL)
1145 		{
1146 			if (CFURLGetFSRef(bundleURL, &fref))
1147 				err = AHRegisterHelpBook(&fref);
1148 
1149 			CFRelease(bundleURL);
1150 		}
1151 	}
1152 }
1153 
SetHIViewID(HIViewID * cid,OSType signature,SInt32 value)1154 void SetHIViewID (HIViewID *cid, OSType signature, SInt32 value)
1155 {
1156 	// Since HIViewID.id conflicts Objective-C 'id'...
1157 
1158 	cid->signature = signature;
1159 	cid->id = value;
1160 }
1161