1 /***********************************************************************************
2   Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3 
4   (c) Copyright 1996 - 2002  Gary Henderson (gary.henderson@ntlworld.com),
5                              Jerremy Koot (jkoot@snes9x.com)
6 
7   (c) Copyright 2002 - 2004  Matthew Kendora
8 
9   (c) Copyright 2002 - 2005  Peter Bortas (peter@bortas.org)
10 
11   (c) Copyright 2004 - 2005  Joel Yliluoma (http://iki.fi/bisqwit/)
12 
13   (c) Copyright 2001 - 2006  John Weidman (jweidman@slip.net)
14 
15   (c) Copyright 2002 - 2006  funkyass (funkyass@spam.shaw.ca),
16                              Kris Bleakley (codeviolation@hotmail.com)
17 
18   (c) Copyright 2002 - 2010  Brad Jorsch (anomie@users.sourceforge.net),
19                              Nach (n-a-c-h@users.sourceforge.net),
20 
21   (c) Copyright 2002 - 2011  zones (kasumitokoduck@yahoo.com)
22 
23   (c) Copyright 2006 - 2007  nitsuja
24 
25   (c) Copyright 2009 - 2016  BearOso,
26                              OV2
27 
28 
29   BS-X C emulator code
30   (c) Copyright 2005 - 2006  Dreamer Nom,
31                              zones
32 
33   C4 x86 assembler and some C emulation code
34   (c) Copyright 2000 - 2003  _Demo_ (_demo_@zsnes.com),
35                              Nach,
36                              zsKnight (zsknight@zsnes.com)
37 
38   C4 C++ code
39   (c) Copyright 2003 - 2006  Brad Jorsch,
40                              Nach
41 
42   DSP-1 emulator code
43   (c) Copyright 1998 - 2006  _Demo_,
44                              Andreas Naive (andreasnaive@gmail.com),
45                              Gary Henderson,
46                              Ivar (ivar@snes9x.com),
47                              John Weidman,
48                              Kris Bleakley,
49                              Matthew Kendora,
50                              Nach,
51                              neviksti (neviksti@hotmail.com)
52 
53   DSP-2 emulator code
54   (c) Copyright 2003         John Weidman,
55                              Kris Bleakley,
56                              Lord Nightmare (lord_nightmare@users.sourceforge.net),
57                              Matthew Kendora,
58                              neviksti
59 
60   DSP-3 emulator code
61   (c) Copyright 2003 - 2006  John Weidman,
62                              Kris Bleakley,
63                              Lancer,
64                              z80 gaiden
65 
66   DSP-4 emulator code
67   (c) Copyright 2004 - 2006  Dreamer Nom,
68                              John Weidman,
69                              Kris Bleakley,
70                              Nach,
71                              z80 gaiden
72 
73   OBC1 emulator code
74   (c) Copyright 2001 - 2004  zsKnight,
75                              pagefault (pagefault@zsnes.com),
76                              Kris Bleakley
77                              Ported from x86 assembler to C by sanmaiwashi
78 
79   SPC7110 and RTC C++ emulator code used in 1.39-1.51
80   (c) Copyright 2002         Matthew Kendora with research by
81                              zsKnight,
82                              John Weidman,
83                              Dark Force
84 
85   SPC7110 and RTC C++ emulator code used in 1.52+
86   (c) Copyright 2009         byuu,
87                              neviksti
88 
89   S-DD1 C emulator code
90   (c) Copyright 2003         Brad Jorsch with research by
91                              Andreas Naive,
92                              John Weidman
93 
94   S-RTC C emulator code
95   (c) Copyright 2001 - 2006  byuu,
96                              John Weidman
97 
98   ST010 C++ emulator code
99   (c) Copyright 2003         Feather,
100                              John Weidman,
101                              Kris Bleakley,
102                              Matthew Kendora
103 
104   Super FX x86 assembler emulator code
105   (c) Copyright 1998 - 2003  _Demo_,
106                              pagefault,
107                              zsKnight
108 
109   Super FX C emulator code
110   (c) Copyright 1997 - 1999  Ivar,
111                              Gary Henderson,
112                              John Weidman
113 
114   Sound emulator code used in 1.5-1.51
115   (c) Copyright 1998 - 2003  Brad Martin
116   (c) Copyright 1998 - 2006  Charles Bilyue'
117 
118   Sound emulator code used in 1.52+
119   (c) Copyright 2004 - 2007  Shay Green (gblargg@gmail.com)
120 
121   S-SMP emulator code used in 1.54+
122   (c) Copyright 2016         byuu
123 
124   SH assembler code partly based on x86 assembler code
125   (c) Copyright 2002 - 2004  Marcus Comstedt (marcus@mc.pp.se)
126 
127   2xSaI filter
128   (c) Copyright 1999 - 2001  Derek Liauw Kie Fa
129 
130   HQ2x, HQ3x, HQ4x filters
131   (c) Copyright 2003         Maxim Stepin (maxim@hiend3d.com)
132 
133   NTSC filter
134   (c) Copyright 2006 - 2007  Shay Green
135 
136   GTK+ GUI code
137   (c) Copyright 2004 - 2016  BearOso
138 
139   Win32 GUI code
140   (c) Copyright 2003 - 2006  blip,
141                              funkyass,
142                              Matthew Kendora,
143                              Nach,
144                              nitsuja
145   (c) Copyright 2009 - 2016  OV2
146 
147   Mac OS GUI code
148   (c) Copyright 1998 - 2001  John Stiles
149   (c) Copyright 2001 - 2011  zones
150 
151 
152   Specific ports contains the works of other authors. See headers in
153   individual files.
154 
155 
156   Snes9x homepage: http://www.snes9x.com/
157 
158   Permission to use, copy, modify and/or distribute Snes9x in both binary
159   and source form, for non-commercial purposes, is hereby granted without
160   fee, providing that this license information and copyright notice appear
161   with all copies and any derived work.
162 
163   This software is provided 'as-is', without any express or implied
164   warranty. In no event shall the authors be held liable for any damages
165   arising from the use of this software or it's derivatives.
166 
167   Snes9x is freeware for PERSONAL USE only. Commercial users should
168   seek permission of the copyright holders first. Commercial use includes,
169   but is not limited to, charging money for Snes9x or software derived from
170   Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
171   using Snes9x as a promotion for your commercial product.
172 
173   The copyright holders request that bug fixes and improvements to the code
174   should be forwarded to them so everyone can benefit from the modifications
175   in future versions.
176 
177   Super NES and Super Nintendo Entertainment System are trademarks of
178   Nintendo Co., Limited and its subsidiary companies.
179  ***********************************************************************************/
180 
181 /***********************************************************************************
182   SNES9X for Mac OS (c) Copyright John Stiles
183 
184   Snes9x for Mac OS X
185 
186   (c) Copyright 2001 - 2011  zones
187   (c) Copyright 2002 - 2005  107
188   (c) Copyright 2002         PB1400c
189   (c) Copyright 2004         Alexander and Sander
190   (c) Copyright 2004 - 2005  Steven Seeger
191   (c) Copyright 2005         Ryan Vogt
192  ***********************************************************************************/
193 
194 
195 #include "snes9x.h"
196 #include "memmap.h"
197 
198 #include "mac-prefix.h"
199 #include "mac-audio.h"
200 #include "mac-joypad.h"
201 #include "mac-keyboard.h"
202 #include "mac-os.h"
203 #include "mac-render.h"
204 #include "mac-stringtools.h"
205 #include "mac-dialog.h"
206 
207 int	autofireLastTabIndex = 1;
208 
209 static int	tabList[] = { 2, 257, 258 };
210 
211 static void RomInfoCopyToClipboard (void);
212 static void RomInfoBuildInfoText (char *);
213 static void AutofireSetAllIconImages (int, HIViewRef);
214 static void AutofireSetIconImages (int, HIViewRef);
215 static void AutofireReadAllSettings (int, HIViewRef);
216 static void AutofireReadSetting (int, uint16, HIViewRef);
217 static void AutofireWriteAllSettings (int, HIViewRef);
218 static void AutofireWriteSetting (int, uint16 *, HIViewRef);
219 static void AutofireSelectTabPane (HIViewRef, SInt16);
220 static OSStatus UpdateTextControlView (HIViewRef);
221 static pascal void AutofireSliderActionProc (HIViewRef, HIViewPartCode);
222 static pascal OSStatus RomInfoEventHandler (EventHandlerCallRef, EventRef, void *);
223 static pascal OSStatus AutofireTabEventHandler (EventHandlerCallRef, EventRef, void *);
224 static pascal OSStatus AutofireWindowEventHandler (EventHandlerCallRef, EventRef, void *);
225 
226 
UpdateTextControlView(HIViewRef control)227 static OSStatus UpdateTextControlView (HIViewRef control)
228 {
229 	OSStatus			err;
230 	WindowAttributes	attr;
231 
232 	err = GetWindowAttributes(GetControlOwner(control), &attr);
233 	if (err == noErr)
234 	{
235 		if (attr & kWindowCompositingAttribute)
236 			err = HIViewSetNeedsDisplay(control, true);
237 		else
238 			Draw1Control(control);
239 	}
240 
241 	return (err);
242 }
243 
SetStaticTextCStr(HIViewRef control,char * text,Boolean draw)244 OSStatus SetStaticTextCStr (HIViewRef control, char *text, Boolean draw)
245 {
246 	OSStatus	err;
247 
248 	if (!control || !text)
249 		return (paramErr);
250 
251 	err = SetControlData(control, 0, kControlStaticTextTextTag, strlen(text), text);
252 	if ((err == noErr) && draw)
253 		err = UpdateTextControlView(control);
254 
255 	return (err);
256 }
257 
SetStaticTextCFString(HIViewRef control,CFStringRef text,Boolean draw)258 OSStatus SetStaticTextCFString (HIViewRef control, CFStringRef text, Boolean draw)
259 {
260 	OSStatus	err;
261 
262 	if (!control || !text)
263 		return (paramErr);
264 
265 	err = SetControlData(control, 0, kControlStaticTextCFStringTag, sizeof(CFStringRef), &text);
266 	if ((err == noErr) && draw)
267 		err = UpdateTextControlView(control);
268 
269 	return (err);
270 }
271 
SetStaticTextTrunc(HIViewRef control,TruncCode mode,Boolean draw)272 OSStatus SetStaticTextTrunc (HIViewRef control, TruncCode mode, Boolean draw)
273 {
274 	OSStatus	err;
275 	TruncCode	trunc;
276 	Boolean		multiline;
277 
278 	if (!control)
279 		return (paramErr);
280 
281 	trunc = mode;
282 	multiline = false;
283 
284 	err = SetControlData(control, 0, kControlStaticTextIsMultilineTag, sizeof(Boolean), &multiline);
285 	if (err == noErr)
286 	{
287 		err = SetControlData(control, 0, kControlStaticTextTruncTag, sizeof(TruncCode), &trunc);
288 		if ((err == noErr) && draw)
289 			err = UpdateTextControlView(control);
290 	}
291 
292 	return (err);
293 }
294 
GetEditTextCStr(HIViewRef control,char * text)295 OSStatus GetEditTextCStr (HIViewRef control, char *text)
296 {
297 	OSStatus	err;
298 	Size		actualSize;
299 
300 	if (!control || !text)
301 		return (paramErr);
302 
303 	err = GetControlData(control, 0, kControlEditTextTextTag, 255, text, &actualSize);
304 	if (err == noErr)
305 		text[actualSize] = 0;
306 
307 	return (err);
308 }
309 
SetEditTextCStr(HIViewRef control,char * text,Boolean draw)310 OSStatus SetEditTextCStr (HIViewRef control, char *text, Boolean draw)
311 {
312 	OSStatus	err;
313 
314 	if (!control || !text)
315 		return (paramErr);
316 
317 	err = SetControlData(control, 0, kControlEditTextTextTag, strlen(text), text);
318 	if ((err == noErr) && draw)
319 		err = UpdateTextControlView(control);
320 
321 	return (err);
322 }
323 
CopyEditTextCFString(HIViewRef control,CFStringRef * text)324 OSStatus CopyEditTextCFString (HIViewRef control, CFStringRef *text)
325 {
326 	OSStatus	err;
327 	Size		actualSize;
328 
329 	if (!control || !text)
330 		return (paramErr);
331 
332 	err = GetControlData(control, 0, kControlEditTextCFStringTag, sizeof(CFStringRef), text, &actualSize);
333 
334 	return (err);
335 }
336 
SetEditTextCFString(HIViewRef control,CFStringRef text,Boolean draw)337 OSStatus SetEditTextCFString (HIViewRef control, CFStringRef text, Boolean draw)
338 {
339 	OSStatus	err;
340 
341 	if (!control || !text)
342 		return (paramErr);
343 
344 	err = SetControlData(control, 0, kControlEditTextCFStringTag, sizeof(CFStringRef), &text);
345 	if ((err == noErr) && draw)
346 		err = UpdateTextControlView(control);
347 
348 	return (err);
349 }
350 
SetEditTextSelection(HIViewRef control,SInt16 selStart,SInt16 selEnd)351 OSStatus SetEditTextSelection (HIViewRef control, SInt16 selStart, SInt16 selEnd)
352 {
353 	OSStatus					err;
354 	ControlEditTextSelectionRec	selection;
355 
356 	if (!control)
357 		return (paramErr);
358 
359 	selection.selStart = selStart;
360 	selection.selEnd   = selEnd;
361 
362 	err = SetControlData(control, 0, kControlEditTextSelectionTag, sizeof(selection), &selection);
363 	if (err == noErr)
364 		err = UpdateTextControlView(control);
365 
366 	return (err);
367 }
368 
StartCarbonModalDialog(void)369 void StartCarbonModalDialog (void)
370 {
371 	HiliteMenu(0);
372 	if (gWindow)
373 		HideWindow(gWindow);
374 }
375 
FinishCarbonModalDialog(void)376 void FinishCarbonModalDialog (void)
377 {
378 	if (gWindow)
379 		ShowWindow(gWindow);
380 }
381 
MoveWindowPosition(WindowRef window,int which,Boolean resize)382 void MoveWindowPosition (WindowRef window, int which, Boolean resize)
383 {
384 	if (savewindowpos)
385 	{
386 		MoveWindow(window, windowPos[which].h, windowPos[which].v, false);
387 
388 		if (resize)
389 		{
390 			if ((windowSize[which].width > 0) && (windowSize[which].height > 0))
391 				SizeWindow(window, (short) windowSize[which].width, (short) windowSize[which].height, false);
392 		}
393 	}
394 	else
395 		RepositionWindow(window, NULL, kWindowAlertPositionOnMainScreen);
396 }
397 
SaveWindowPosition(WindowRef window,int which)398 void SaveWindowPosition (WindowRef window, int which)
399 {
400 	Rect	rct;
401 
402 	GetWindowBounds(window, kWindowContentRgn, &rct);
403 	windowPos[which].h = rct.left;
404 	windowPos[which].v = rct.top;
405 	windowSize[which].width  = (float) (rct.right  - rct.left);
406 	windowSize[which].height = (float) (rct.bottom - rct.top );
407 }
408 
AppearanceAlert(AlertType type,int stringID1,int stringID2)409 void AppearanceAlert (AlertType type, int stringID1, int stringID2)
410 {
411 	OSStatus		err;
412 	DialogRef		dialog;
413 	DialogItemIndex	outItemHit;
414 	CFStringRef		key1, key2, mes1, mes2;
415 	char			label1[32], label2[32];
416 
417 	sprintf(label1, "AlertMes_%02d", stringID1);
418 	sprintf(label2, "AlertMes_%02d", stringID2);
419 
420 	key1 = CFStringCreateWithCString(kCFAllocatorDefault, label1, CFStringGetSystemEncoding());
421 	key2 = CFStringCreateWithCString(kCFAllocatorDefault, label2, CFStringGetSystemEncoding());
422 
423 	if (key1) mes1 = CFCopyLocalizedString(key1, "mes1");	else mes1 = NULL;
424 	if (key2) mes2 = CFCopyLocalizedString(key2, "mes2");	else mes2 = NULL;
425 
426 	PlayAlertSound();
427 
428 	err = CreateStandardAlert(type, mes1, mes2, NULL, &dialog);
429 	err = RunStandardAlert(dialog, NULL, &outItemHit);
430 
431 	if (key1) CFRelease(key1);
432 	if (key2) CFRelease(key2);
433 	if (mes1) CFRelease(mes1);
434 	if (mes2) CFRelease(mes2);
435 }
436 
AboutDialog(void)437 void AboutDialog (void)
438 {
439 	OSStatus	err;
440 	IBNibRef	nibRef;
441 
442 	err = CreateNibReference(kMacS9XCFString, &nibRef);
443 	if (err == noErr)
444 	{
445 		WindowRef	tWindowRef;
446 
447 		err = CreateWindowFromNib(nibRef, CFSTR("About"), &tWindowRef);
448 		if (err == noErr)
449 		{
450 			EventHandlerRef		eref;
451 			EventHandlerUPP		eventUPP;
452 			EventTypeSpec		windowEvents[] = { { kEventClassWindow,  kEventWindowClose         },
453 												   { kEventClassCommand, kEventCommandUpdateStatus } };
454 			ControlFontStyleRec	frec;
455 			HIViewRef			ctl, root;
456 			HIViewID			cid;
457 			char				text[32];
458 
459 			err = ChangeWindowAttributes(tWindowRef, kWindowNoAttributes, kWindowInWindowMenuAttribute);
460 
461 			if (systemVersion >= 0x1040)
462 				frec.font = FMGetFontFromATSFontRef(ATSFontFindFromName(CFSTR("Lucida Grande"), kATSOptionFlagsDefault));
463 		#ifdef MAC_PANTHER_SUPPORT
464 			else
465 				frec.font = kThemeSystemFont;
466 		#endif
467 			frec.just = teCenter;
468 
469 			root = HIViewGetRoot(tWindowRef);
470 			cid.id = 0;
471 
472 			cid.signature = 'VERS';
473 			HIViewFindByID(root, cid, &ctl);
474 			sprintf(text, "Version %s (%s)", VERSION, MAC_VERSION);
475 			SetStaticTextCStr(ctl, text, false);
476 			frec.flags = kControlUseFontMask | kControlUseSizeMask | kControlUseJustMask;
477 			frec.size  = 10;
478 			err = SetControlFontStyle(ctl, &frec);
479 
480 			cid.signature = 'NAME';
481 			HIViewFindByID(root, cid, &ctl);
482 			frec.flags = kControlUseFontMask | kControlUseSizeMask | kControlUseFaceMask | kControlUseJustMask;
483 			frec.size  = 14;
484 			frec.style = 1;
485 			err = SetControlFontStyle(ctl, &frec);
486 
487 			eventUPP = NewEventHandlerUPP(DefaultEventHandler);
488 			err = InstallWindowEventHandler(tWindowRef, eventUPP, GetEventTypeCount(windowEvents), windowEvents, (void *) tWindowRef, &eref);
489 
490 			MoveWindowPosition(tWindowRef, kWindowAbout, false);
491 			ShowWindow(tWindowRef);
492 			err = RunAppModalLoopForWindow(tWindowRef);
493 			HideWindow(tWindowRef);
494 			SaveWindowPosition(tWindowRef, kWindowAbout);
495 
496 			err = RemoveEventHandler(eref);
497 			DisposeEventHandlerUPP(eventUPP);
498 
499 			CFRelease(tWindowRef);
500 		}
501 
502 		DisposeNibReference(nibRef);
503 	}
504 }
505 
DefaultEventHandler(EventHandlerCallRef inHandlerRef,EventRef inEvent,void * inUserData)506 pascal OSStatus DefaultEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
507 {
508 	OSStatus	err, result = eventNotHandledErr;
509 	WindowRef	tWindowRef = (WindowRef) inUserData;
510 
511 	switch (GetEventClass(inEvent))
512 	{
513 		case kEventClassWindow:
514 			switch (GetEventKind(inEvent))
515 			{
516 				case kEventWindowClose:
517 					QuitAppModalLoopForWindow(tWindowRef);
518 					result = noErr;
519 			}
520 
521 			break;
522 
523 		case kEventClassCommand:
524 			switch (GetEventKind(inEvent))
525 			{
526 				case kEventCommandUpdateStatus:
527 					HICommand	tHICommand;
528 
529 					err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
530 					if (err == noErr && tHICommand.commandID == 'clos')
531 					{
532 						UpdateMenuCommandStatus(true);
533 						result = noErr;
534 					}
535 			}
536 
537 			break;
538 	}
539 
540 	return (result);
541 }
542 
ConfigureAutofire(void)543 void ConfigureAutofire (void)
544 {
545 	OSStatus	err;
546 	IBNibRef	nibRef;
547 
548 	err = CreateNibReference(kMacS9XCFString, &nibRef);
549 	if (err == noErr)
550 	{
551 		WindowRef	tWindowRef;
552 
553 		err = CreateWindowFromNib(nibRef, CFSTR("AutoFire"), &tWindowRef);
554 		if (err == noErr)
555 		{
556 			EventHandlerRef		wRef, tRef;
557 			EventHandlerUPP		wUPP, tUPP;
558 			EventTypeSpec		wEvent[] = { { kEventClassWindow,  kEventWindowClose         },
559 											 { kEventClassCommand, kEventCommandProcess      },
560 											 { kEventClassCommand, kEventCommandUpdateStatus } },
561 								tEvent[] = { { kEventClassControl, kEventControlHit          } };
562 			ControlActionUPP	actionUPP;
563 			HIViewRef			ctl, root;
564 			HIViewID			cid;
565 
566 			root = HIViewGetRoot(tWindowRef);
567 
568 			wUPP = NewEventHandlerUPP(AutofireWindowEventHandler);
569 			err = InstallWindowEventHandler(tWindowRef, wUPP, GetEventTypeCount(wEvent), wEvent, (void *) tWindowRef, &wRef);
570 
571 			cid.signature = 'Ftab';
572 			cid.id = 256;
573 			HIViewFindByID(root, cid, &ctl);
574 			SetControl32BitValue(ctl, autofireLastTabIndex);
575 			AutofireSelectTabPane(ctl, autofireLastTabIndex);
576 			tUPP = NewEventHandlerUPP(AutofireTabEventHandler);
577 			err = InstallControlEventHandler(ctl, tUPP, GetEventTypeCount(tEvent), tEvent, 0, &tRef);
578 
579 			actionUPP = NewControlActionUPP(AutofireSliderActionProc);
580 
581 			for (int player = 0; player < 2; player++)
582 			{
583 				AutofireSetAllIconImages(player + 1, root);
584 				AutofireReadAllSettings(player + 1, root);
585 
586 				cid.id = player + 1;
587 				cid.signature = 'Slid';
588 				HIViewFindByID(root, cid, &ctl);
589 				SetControlAction(ctl, actionUPP);
590 			}
591 
592 			MoveWindowPosition(tWindowRef, kWindowAutoFire, false);
593 			ShowWindow(tWindowRef);
594 			err = RunAppModalLoopForWindow(tWindowRef);
595 			HideWindow(tWindowRef);
596 			SaveWindowPosition(tWindowRef, kWindowAutoFire);
597 
598 			for (int player = 0; player < 2; player++)
599 				AutofireWriteAllSettings(player + 1, root);
600 
601 			autofire = (autofireRec[0].buttonMask || autofireRec[1].buttonMask) ? true : false;
602 
603 			err = RemoveEventHandler(tRef);
604 			DisposeEventHandlerUPP(tUPP);
605 
606 			err = RemoveEventHandler(wRef);
607 			DisposeEventHandlerUPP(wUPP);
608 
609 			DisposeControlActionUPP(actionUPP);
610 
611 			CFRelease(tWindowRef);
612 		}
613 
614 		DisposeNibReference(nibRef);
615 	}
616 }
617 
AutofireSetAllIconImages(int player,HIViewRef parent)618 static void AutofireSetAllIconImages (int player, HIViewRef parent)
619 {
620 	AutofireSetIconImages(player * 1,    parent);
621 	AutofireSetIconImages(player * 11,   parent);
622 	AutofireSetIconImages(player * 111,  parent);
623 	AutofireSetIconImages(player * 1111, parent);
624 }
625 
AutofireSetIconImages(int sig,HIViewRef parent)626 static void AutofireSetIconImages (int sig, HIViewRef parent)
627 {
628 	OSStatus					err;
629 	ControlButtonContentInfo	info;
630 	HIViewRef					ctl;
631 	HIViewID					cid;
632 	int							ofs;
633 
634 	cid.id = sig;
635 	ofs = macPadIconIndex + ((sig % 2) ? 0 : 12);
636 
637 	if (systemVersion >= 0x1040)
638 	{
639 		info.contentType = kControlContentCGImageRef;
640 
641 		cid.signature = 'AChk';
642 		HIViewFindByID(parent, cid, &ctl);
643 		info.u.imageRef = macIconImage[7 + ofs];
644 		err = SetBevelButtonContentInfo(ctl, &info);
645 
646 		cid.signature = 'BChk';
647 		HIViewFindByID(parent, cid, &ctl);
648 		info.u.imageRef = macIconImage[5 + ofs];
649 		err = SetBevelButtonContentInfo(ctl, &info);
650 
651 		cid.signature = 'XChk';
652 		HIViewFindByID(parent, cid, &ctl);
653 		info.u.imageRef = macIconImage[6 + ofs];
654 		err = SetBevelButtonContentInfo(ctl, &info);
655 
656 		cid.signature = 'YChk';
657 		HIViewFindByID(parent, cid, &ctl);
658 		info.u.imageRef = macIconImage[4 + ofs];
659 		err = SetBevelButtonContentInfo(ctl, &info);
660 
661 		cid.signature = 'LChk';
662 		HIViewFindByID(parent, cid, &ctl);
663 		info.u.imageRef = macIconImage[8 + ofs];
664 		err = SetBevelButtonContentInfo(ctl, &info);
665 
666 		cid.signature = 'RChk';
667 		HIViewFindByID(parent, cid, &ctl);
668 		info.u.imageRef = macIconImage[9 + ofs];
669 		err = SetBevelButtonContentInfo(ctl, &info);
670 
671 		cid.signature = 'Up  ';
672 		HIViewFindByID(parent, cid, &ctl);
673 		info.u.imageRef = macIconImage[0 + ofs];
674 		err = SetBevelButtonContentInfo(ctl, &info);
675 
676 		cid.signature = 'Down';
677 		HIViewFindByID(parent, cid, &ctl);
678 		info.u.imageRef = macIconImage[1 + ofs];
679 		err = SetBevelButtonContentInfo(ctl, &info);
680 
681 		cid.signature = 'Left';
682 		HIViewFindByID(parent, cid, &ctl);
683 		info.u.imageRef = macIconImage[2 + ofs];
684 		err = SetBevelButtonContentInfo(ctl, &info);
685 
686 		cid.signature = 'Righ';
687 		HIViewFindByID(parent, cid, &ctl);
688 		info.u.imageRef = macIconImage[3 + ofs];
689 		err = SetBevelButtonContentInfo(ctl, &info);
690 
691 		cid.signature = 'Star';
692 		HIViewFindByID(parent, cid, &ctl);
693 		info.u.imageRef = macIconImage[10 + ofs];
694 		err = SetBevelButtonContentInfo(ctl, &info);
695 
696 		cid.signature = 'Sele';
697 		HIViewFindByID(parent, cid, &ctl);
698 		info.u.imageRef = macIconImage[11 + ofs];
699 		err = SetBevelButtonContentInfo(ctl, &info);
700 	}
701 #ifdef MAC_PANTHER_SUPPORT
702 	else
703 	{
704 		info.contentType = kControlContentIconRef;
705 
706 		cid.signature = 'AChk';
707 		HIViewFindByID(parent, cid, &ctl);
708 		info.u.iconRef = macIconRef[7 + ofs];
709 		err = SetBevelButtonContentInfo(ctl, &info);
710 
711 		cid.signature = 'BChk';
712 		HIViewFindByID(parent, cid, &ctl);
713 		info.u.iconRef = macIconRef[5 + ofs];
714 		err = SetBevelButtonContentInfo(ctl, &info);
715 
716 		cid.signature = 'XChk';
717 		HIViewFindByID(parent, cid, &ctl);
718 		info.u.iconRef = macIconRef[6 + ofs];
719 		err = SetBevelButtonContentInfo(ctl, &info);
720 
721 		cid.signature = 'YChk';
722 		HIViewFindByID(parent, cid, &ctl);
723 		info.u.iconRef = macIconRef[4 + ofs];
724 		err = SetBevelButtonContentInfo(ctl, &info);
725 
726 		cid.signature = 'LChk';
727 		HIViewFindByID(parent, cid, &ctl);
728 		info.u.iconRef = macIconRef[8 + ofs];
729 		err = SetBevelButtonContentInfo(ctl, &info);
730 
731 		cid.signature = 'RChk';
732 		HIViewFindByID(parent, cid, &ctl);
733 		info.u.iconRef = macIconRef[9 + ofs];
734 		err = SetBevelButtonContentInfo(ctl, &info);
735 
736 		cid.signature = 'Up  ';
737 		HIViewFindByID(parent, cid, &ctl);
738 		info.u.iconRef = macIconRef[0 + ofs];
739 		err = SetBevelButtonContentInfo(ctl, &info);
740 
741 		cid.signature = 'Down';
742 		HIViewFindByID(parent, cid, &ctl);
743 		info.u.iconRef = macIconRef[1 + ofs];
744 		err = SetBevelButtonContentInfo(ctl, &info);
745 
746 		cid.signature = 'Left';
747 		HIViewFindByID(parent, cid, &ctl);
748 		info.u.iconRef = macIconRef[2 + ofs];
749 		err = SetBevelButtonContentInfo(ctl, &info);
750 
751 		cid.signature = 'Righ';
752 		HIViewFindByID(parent, cid, &ctl);
753 		info.u.iconRef = macIconRef[3 + ofs];
754 		err = SetBevelButtonContentInfo(ctl, &info);
755 
756 		cid.signature = 'Star';
757 		HIViewFindByID(parent, cid, &ctl);
758 		info.u.iconRef = macIconRef[10 + ofs];
759 		err = SetBevelButtonContentInfo(ctl, &info);
760 
761 		cid.signature = 'Sele';
762 		HIViewFindByID(parent, cid, &ctl);
763 		info.u.iconRef = macIconRef[11 + ofs];
764 		err = SetBevelButtonContentInfo(ctl, &info);
765 	}
766 #endif
767 }
768 
AutofireReadAllSettings(int player,HIViewRef parent)769 static void AutofireReadAllSettings (int player, HIViewRef parent)
770 {
771 	HIViewRef	ctl;
772 	HIViewID	cid;
773 	char		num[10];
774 
775 	AutofireReadSetting(player * 1,    autofireRec[player - 1].buttonMask, parent);
776 	AutofireReadSetting(player * 11,   autofireRec[player - 1].toggleMask, parent);
777 	AutofireReadSetting(player * 111,  autofireRec[player - 1].tcMask,     parent);
778 	AutofireReadSetting(player * 1111, autofireRec[player - 1].invertMask, parent);
779 
780 	cid.id = player;
781 
782 	cid.signature = 'Num_';
783 	HIViewFindByID(parent, cid, &ctl);
784 	sprintf(num, "%ld", autofireRec[player - 1].frequency);
785 	SetStaticTextCStr(ctl, num, false);
786 
787 	cid.signature = 'Slid';
788 	HIViewFindByID(parent, cid, &ctl);
789 	SetControl32BitValue(ctl, autofireRec[player - 1].frequency);
790 }
791 
AutofireReadSetting(int sig,uint16 target,HIViewRef parent)792 static void AutofireReadSetting (int sig, uint16 target, HIViewRef parent)
793 {
794 	HIViewRef	ctl;
795 	HIViewID	cid;
796 
797 	cid.id = sig;
798 
799 	cid.signature = 'AChk';
800 	HIViewFindByID(parent, cid, &ctl);
801 	SetControl32BitValue(ctl, (target & 0x0080) ? 1 : 0);
802 
803 	cid.signature = 'BChk';
804 	HIViewFindByID(parent, cid, &ctl);
805 	SetControl32BitValue(ctl, (target & 0x8000) ? 1 : 0);
806 
807 	cid.signature = 'XChk';
808 	HIViewFindByID(parent, cid, &ctl);
809 	SetControl32BitValue(ctl, (target & 0x0040) ? 1 : 0);
810 
811 	cid.signature = 'YChk';
812 	HIViewFindByID(parent, cid, &ctl);
813 	SetControl32BitValue(ctl, (target & 0x4000) ? 1 : 0);
814 
815 	cid.signature = 'LChk';
816 	HIViewFindByID(parent, cid, &ctl);
817 	SetControl32BitValue(ctl, (target & 0x0020) ? 1 : 0);
818 
819 	cid.signature = 'RChk';
820 	HIViewFindByID(parent, cid, &ctl);
821 	SetControl32BitValue(ctl, (target & 0x0010) ? 1 : 0);
822 
823 	cid.signature = 'Up  ';
824 	HIViewFindByID(parent, cid, &ctl);
825 	SetControl32BitValue(ctl, (target & 0x0800) ? 1 : 0);
826 
827 	cid.signature = 'Down';
828 	HIViewFindByID(parent, cid, &ctl);
829 	SetControl32BitValue(ctl, (target & 0x0400) ? 1 : 0);
830 
831 	cid.signature = 'Left';
832 	HIViewFindByID(parent, cid, &ctl);
833 	SetControl32BitValue(ctl, (target & 0x0200) ? 1 : 0);
834 
835 	cid.signature = 'Righ';
836 	HIViewFindByID(parent, cid, &ctl);
837 	SetControl32BitValue(ctl, (target & 0x0100) ? 1 : 0);
838 
839 	cid.signature = 'Star';
840 	HIViewFindByID(parent, cid, &ctl);
841 	SetControl32BitValue(ctl, (target & 0x1000) ? 1 : 0);
842 
843 	cid.signature = 'Sele';
844 	HIViewFindByID(parent, cid, &ctl);
845 	SetControl32BitValue(ctl, (target & 0x2000) ? 1 : 0);
846 }
847 
AutofireWriteAllSettings(int player,HIViewRef parent)848 static void AutofireWriteAllSettings (int player, HIViewRef parent)
849 {
850 	HIViewRef	ctl;
851 	HIViewID	cid;
852 
853 	AutofireWriteSetting(player * 1,    &(autofireRec[player - 1].buttonMask), parent);
854 	AutofireWriteSetting(player * 11,   &(autofireRec[player - 1].toggleMask), parent);
855 	AutofireWriteSetting(player * 111,  &(autofireRec[player - 1].tcMask),     parent);
856 	AutofireWriteSetting(player * 1111, &(autofireRec[player - 1].invertMask), parent);
857 
858 	cid.id = player;
859 	cid.signature = 'Slid';
860 	HIViewFindByID(parent, cid, &ctl);
861 	autofireRec[player - 1].frequency = GetControl32BitValue(ctl);
862 }
863 
AutofireWriteSetting(int sig,uint16 * target,HIViewRef parent)864 static void AutofireWriteSetting (int sig, uint16 *target, HIViewRef parent)
865 {
866 	HIViewRef	ctl;
867 	HIViewID	cid;
868 
869 	cid.id = sig;
870 	*target = 0x0000;
871 
872 	cid.signature = 'AChk';
873 	HIViewFindByID(parent, cid, &ctl);
874 	if (GetControl32BitValue(ctl))
875 		(*target) |= 0x0080;
876 
877 	cid.signature = 'BChk';
878 	HIViewFindByID(parent, cid, &ctl);
879 	if (GetControl32BitValue(ctl))
880 		(*target) |= 0x8000;
881 
882 	cid.signature = 'XChk';
883 	HIViewFindByID(parent, cid, &ctl);
884 	if (GetControl32BitValue(ctl))
885 		(*target) |= 0x0040;
886 
887 	cid.signature = 'YChk';
888 	HIViewFindByID(parent, cid, &ctl);
889 	if (GetControl32BitValue(ctl))
890 		(*target) |= 0x4000;
891 
892 	cid.signature = 'LChk';
893 	HIViewFindByID(parent, cid, &ctl);
894 	if (GetControl32BitValue(ctl))
895 		(*target) |= 0x0020;
896 
897 	cid.signature = 'RChk';
898 	HIViewFindByID(parent, cid, &ctl);
899 	if (GetControl32BitValue(ctl))
900 		(*target) |= 0x0010;
901 
902 	cid.signature = 'Up  ';
903 	HIViewFindByID(parent, cid, &ctl);
904 	if (GetControl32BitValue(ctl))
905 		(*target) |= 0x0800;
906 
907 	cid.signature = 'Down';
908 	HIViewFindByID(parent, cid, &ctl);
909 	if (GetControl32BitValue(ctl))
910 		(*target) |= 0x0400;
911 
912 	cid.signature = 'Left';
913 	HIViewFindByID(parent, cid, &ctl);
914 	if (GetControl32BitValue(ctl))
915 		(*target) |= 0x0200;
916 
917 	cid.signature = 'Righ';
918 	HIViewFindByID(parent, cid, &ctl);
919 	if (GetControl32BitValue(ctl))
920 		(*target) |= 0x0100;
921 
922 	cid.signature = 'Star';
923 	HIViewFindByID(parent, cid, &ctl);
924 	if (GetControl32BitValue(ctl))
925 		(*target) |= 0x1000;
926 
927 	cid.signature = 'Sele';
928 	HIViewFindByID(parent, cid, &ctl);
929 	if (GetControl32BitValue(ctl))
930 		(*target) |= 0x2000;
931 }
932 
AutofireSelectTabPane(HIViewRef tabControl,SInt16 index)933 static void AutofireSelectTabPane (HIViewRef tabControl, SInt16 index)
934 {
935 	HIViewRef	sup, userPane, selectedPane = NULL;
936 	HIViewID	cid;
937 
938 	autofireLastTabIndex = index;
939 
940 	sup = HIViewGetSuperview(tabControl);
941 	cid.signature = 'Ftab';
942 
943 	for (int i = 1; i < tabList[0] + 1; i++)
944 	{
945 		cid.id = tabList[i];
946 		HIViewFindByID(sup, cid, &userPane);
947 
948 		if (i == index)
949 			selectedPane = userPane;
950 		else
951 			HIViewSetVisible(userPane, false);
952 	}
953 
954 	if (selectedPane != NULL)
955 		HIViewSetVisible(selectedPane, true);
956 
957 	HIViewSetNeedsDisplay(tabControl, true);
958 }
959 
AutofireTabEventHandler(EventHandlerCallRef inHandlerRef,EventRef inEvent,void * inUserData)960 static pascal OSStatus AutofireTabEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
961 {
962 	OSStatus	err, result = eventNotHandledErr;
963 	HIViewRef	ctl;
964 	HIViewID	cid;
965 	SInt32		value;
966 
967 	err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &ctl);
968 	if (err == noErr)
969 	{
970 		GetControlID(ctl, &cid);
971 		value = GetControl32BitValue(ctl);
972 
973 		if ((cid.id == 256) && (value != autofireLastTabIndex))
974 		{
975 			AutofireSelectTabPane(ctl, value);
976 			result = noErr;
977 		}
978 	}
979 
980 	return (result);
981 }
982 
AutofireWindowEventHandler(EventHandlerCallRef inHandlerRef,EventRef inEvent,void * inUserData)983 static pascal OSStatus AutofireWindowEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
984 {
985 	OSStatus	err, result = eventNotHandledErr;
986 	WindowRef	tWindowRef = (WindowRef) inUserData;
987 
988 	switch (GetEventClass(inEvent))
989 	{
990 		case kEventClassWindow:
991 			switch (GetEventKind(inEvent))
992 			{
993 				case kEventWindowClose:
994 					QuitAppModalLoopForWindow(tWindowRef);
995 					result = noErr;
996 			}
997 
998 			break;
999 
1000 		case kEventClassCommand:
1001 			switch (GetEventKind(inEvent))
1002 			{
1003 				HICommand	tHICommand;
1004 
1005 				case kEventCommandUpdateStatus:
1006 					err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
1007 					if (err == noErr && tHICommand.commandID == 'clos')
1008 					{
1009 						UpdateMenuCommandStatus(true);
1010 						result = noErr;
1011 					}
1012 
1013 					break;
1014 
1015 				case kEventCommandProcess:
1016 					HIViewRef	root;
1017 					int			player = -1;
1018 
1019 					root = HIViewGetRoot(tWindowRef);
1020 
1021 					err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
1022 					if (err == noErr)
1023 					{
1024 						switch (tHICommand.commandID)
1025 						{
1026 							case 'DEF1':
1027 								player = 0;
1028 								break;
1029 
1030 							case 'DEF2':
1031 								player = 1;
1032 								break;
1033 						}
1034 
1035 						if (player != -1)
1036 						{
1037 							autofireRec[player].buttonMask = 0x0000;
1038 							autofireRec[player].toggleMask = 0xFFF0;
1039 							autofireRec[player].tcMask     = 0x0000;
1040 							autofireRec[player].invertMask = 0x0000;
1041 							autofireRec[player].frequency  = 10;
1042 							AutofireReadAllSettings(player + 1, root);
1043 
1044 							result = noErr;
1045 						}
1046 					}
1047 			}
1048 	}
1049 
1050 	return (result);
1051 }
1052 
AutofireSliderActionProc(HIViewRef slider,HIViewPartCode partCode)1053 static pascal void AutofireSliderActionProc (HIViewRef slider, HIViewPartCode partCode)
1054 {
1055 	HIViewRef	ctl;
1056 	HIViewID	cid;
1057 	char		num[10];
1058 
1059 	GetControlID(slider, &cid);
1060 	cid.signature = 'Num_';
1061 	HIViewFindByID(HIViewGetSuperview(slider), cid, &ctl);
1062 
1063 	sprintf(num, "%ld", GetControl32BitValue(slider));
1064 	SetStaticTextCStr(ctl, num, true);
1065 }
1066 
RomInfoDialog(void)1067 void RomInfoDialog (void)
1068 {
1069 	OSStatus	err;
1070 	IBNibRef	nibRef;
1071 
1072 	if (!cartOpen)
1073 		return;
1074 
1075 	err = CreateNibReference(kMacS9XCFString, &nibRef);
1076 	if (err == noErr)
1077 	{
1078 		WindowRef	tWindowRef;
1079 
1080 		err = CreateWindowFromNib(nibRef, CFSTR("RomInfo"), &tWindowRef);
1081 		if (err == noErr)
1082 		{
1083 			EventHandlerRef	eref;
1084 			EventHandlerUPP	eventUPP;
1085 			EventTypeSpec	windowEvents[] = { { kEventClassWindow,  kEventWindowClose         },
1086 											   { kEventClassCommand, kEventCommandProcess      },
1087 											   { kEventClassCommand, kEventCommandUpdateStatus } };
1088 			CFStringRef		sref;
1089 			HIViewRef		ctl, root;
1090 			HIViewID		cid;
1091 			char			text[256];
1092 
1093 			eventUPP = NewEventHandlerUPP(RomInfoEventHandler);
1094 			err = InstallWindowEventHandler(tWindowRef, eventUPP, GetEventTypeCount(windowEvents), windowEvents, (void *) tWindowRef, &eref);
1095 
1096 			root = HIViewGetRoot(tWindowRef);
1097 			cid.id = 0;
1098 
1099 			cid.signature = 'Name';	// Cart Name
1100 			HIViewFindByID(root, cid, &ctl);
1101 
1102 			strcpy(text, Memory.RawROMName);
1103 			sref = CopyFixNameStrings(text, Memory.ROMRegion);
1104 			if (!sref)
1105 				SetStaticTextCFString(ctl, CFSTR("unknown"), false);
1106 			else
1107 			{
1108 				SetStaticTextCFString(ctl, sref, false);
1109 				CFRelease(sref);
1110 			}
1111 
1112 			cid.signature = 'Code';	// Game Code
1113 			HIViewFindByID(root, cid, &ctl);
1114 			sprintf(text, "%s", Memory.ROMId);
1115 			SetStaticTextCStr(ctl, text, false);
1116 
1117 			cid.signature = 'Cont';	// Contents
1118 			HIViewFindByID(root, cid, &ctl);
1119 			sprintf(text, "%s", Memory.KartContents());
1120 			SetStaticTextCStr(ctl, text, false);
1121 
1122 			cid.signature = 'Map ';	// ROM Map
1123 			HIViewFindByID(root, cid, &ctl);
1124 			sprintf(text, "%s", Memory.MapType());
1125 			SetStaticTextCStr(ctl, text, false);
1126 
1127 			cid.signature = 'Spee';	// ROM Speed
1128 			HIViewFindByID(root, cid, &ctl);
1129 			sprintf(text, "0x%02X (%s)", Memory.ROMSpeed, ((Memory.ROMSpeed & 0x10) != 0) ? "FastROM" : "SlowROM");
1130 			SetStaticTextCStr(ctl, text, false);
1131 
1132 			cid.signature = 'Type';	// ROM Type
1133 			HIViewFindByID(root, cid, &ctl);
1134 			sprintf(text, "0x%02X", Memory.ROMType);
1135 			SetStaticTextCStr(ctl, text, false);
1136 
1137 			cid.signature = 'SizC';	// Actual ROM Size
1138 			HIViewFindByID(root, cid, &ctl);
1139 			sprintf(text, "%dMbits", Memory.CalculatedSize / 0x20000);
1140 			SetStaticTextCStr(ctl, text, false);
1141 
1142 			cid.signature = 'SizH';	// ROM Size written in info block
1143 			HIViewFindByID(root, cid, &ctl);
1144 			sprintf(text, "%s", Memory.Size());
1145 			SetStaticTextCStr(ctl, text, false);
1146 
1147 			cid.signature = 'SRAM';	// SRAM Size
1148 			HIViewFindByID(root, cid, &ctl);
1149 			sprintf(text, "%s", Memory.StaticRAMSize());
1150 			SetStaticTextCStr(ctl, text, false);
1151 
1152 			cid.signature = 'SumC';	// Actual checksum
1153 			HIViewFindByID(root, cid, &ctl);
1154 			sprintf(text, "0x%04X", Memory.CalculatedChecksum);
1155 			SetStaticTextCStr(ctl, text, false);
1156 
1157 			cid.signature = 'SumH';	// Checksum written in info block
1158 			HIViewFindByID(root, cid, &ctl);
1159 			sprintf(text, "0x%04X", Memory.ROMChecksum);
1160 			SetStaticTextCStr(ctl, text, false);
1161 
1162 			cid.signature = 'ComH';	// Checksum complement written in info block : SumH + ComH = 0xFFFF
1163 			HIViewFindByID(root, cid, &ctl);
1164 			sprintf(text, "0x%04X", Memory.ROMComplementChecksum);
1165 			SetStaticTextCStr(ctl, text, false);
1166 
1167 			cid.signature = 'Outp';	// Video output (NTSC or PAL)
1168 			HIViewFindByID(root, cid, &ctl);
1169 			sprintf(text, "%s", (Memory.ROMRegion > 12 || Memory.ROMRegion < 2) ? "NTSC 60Hz" : "PAL 50Hz");
1170 			SetStaticTextCStr(ctl, text, false);
1171 
1172 			cid.signature = 'Vers';	// Revision
1173 			HIViewFindByID(root, cid, &ctl);
1174 			sprintf(text, "%s", Memory.Revision());
1175 			SetStaticTextCStr(ctl, text, false);
1176 
1177 			cid.signature = 'Lice';	// Licensee
1178 			HIViewFindByID(root, cid, &ctl);
1179 			sprintf(text, "%s", Memory.PublishingCompany());
1180 			SetStaticTextCStr(ctl, text, false);
1181 
1182 			cid.signature = 'Regi';	// Region
1183 			HIViewFindByID(root, cid, &ctl);
1184 			sprintf(text, "%s", Memory.Country());
1185 			SetStaticTextCStr(ctl, text, false);
1186 
1187 			cid.signature = 'CRC ';	// CRC32
1188 			HIViewFindByID(root, cid, &ctl);
1189 			sprintf(text, "0x%08X", Memory.ROMCRC32);
1190 			SetStaticTextCStr(ctl, text, false);
1191 
1192 			MoveWindowPosition(tWindowRef, kWindowRomInfo, false);
1193 			ShowWindow(tWindowRef);
1194 			err = RunAppModalLoopForWindow(tWindowRef);
1195 			HideWindow(tWindowRef);
1196 			SaveWindowPosition(tWindowRef, kWindowRomInfo);
1197 
1198 			err = RemoveEventHandler(eref);
1199 			DisposeEventHandlerUPP(eventUPP);
1200 
1201 			CFRelease(tWindowRef);
1202 		}
1203 
1204 		DisposeNibReference(nibRef);
1205 	}
1206 }
1207 
RomInfoCopyToClipboard(void)1208 static void RomInfoCopyToClipboard (void)
1209 {
1210 	OSStatus			err;
1211 	PasteboardRef		clipboard;
1212 	PasteboardSyncFlags	sync;
1213 	CFDataRef			cfdata;
1214 	char				text[1024];
1215 
1216 	RomInfoBuildInfoText(text);
1217 
1218 	err = PasteboardCreate(kPasteboardClipboard, &clipboard);
1219 	if (err == noErr)
1220 	{
1221 		err = PasteboardClear(clipboard);
1222 		if (err == noErr)
1223 		{
1224 			sync = PasteboardSynchronize(clipboard);
1225 			if (!(sync & kPasteboardModified) && (sync & kPasteboardClientIsOwner))
1226 			{
1227 				cfdata = CFDataCreate(kCFAllocatorDefault, (UInt8 *) text, (CFIndex) strlen(text));
1228 				if (cfdata)
1229 				{
1230 					err = PasteboardPutItemFlavor(clipboard, (PasteboardItemID) 1, CFSTR("com.apple.traditional-mac-plain-text"), cfdata, 0);
1231 					CFRelease(cfdata);
1232 				}
1233 			}
1234 		}
1235 
1236 		CFRelease(clipboard);
1237 	}
1238 }
1239 
RomInfoBuildInfoText(char * romtext)1240 static void RomInfoBuildInfoText (char *romtext)
1241 {
1242 	char	s1[256], s2[1024];
1243 
1244 	sprintf(s1, "Snes9x version: %s\nMac port version: %s, ", VERSION, MAC_VERSION);
1245 #ifdef __BIG_ENDIAN__
1246 	strcat(s1, "PowerPC\n\n");
1247 #else
1248 	strcat(s1, "Intel\n\n");
1249 #endif
1250 	Memory.MakeRomInfoText(s2);
1251 	sprintf(romtext, "%s%s", s1, s2);
1252 }
1253 
RomInfoEventHandler(EventHandlerCallRef inHandlerRef,EventRef inEvent,void * inUserData)1254 static pascal OSStatus RomInfoEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
1255 {
1256 	OSStatus	err, result = eventNotHandledErr;
1257 	WindowRef	tWindowRef = (WindowRef) inUserData;
1258 
1259 	switch (GetEventClass(inEvent))
1260 	{
1261 		case kEventClassWindow:
1262 			switch (GetEventKind(inEvent))
1263 			{
1264 				case kEventWindowClose:
1265 					QuitAppModalLoopForWindow(tWindowRef);
1266 					result = noErr;
1267 			}
1268 
1269 			break;
1270 
1271 		case kEventClassCommand:
1272 			switch (GetEventKind(inEvent))
1273 			{
1274 				HICommand	tHICommand;
1275 
1276 				case kEventCommandUpdateStatus:
1277 					err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
1278 					if (err == noErr && tHICommand.commandID == 'clos')
1279 					{
1280 						UpdateMenuCommandStatus(true);
1281 						result = noErr;
1282 					}
1283 
1284 					break;
1285 
1286 				case kEventCommandProcess:
1287 					err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
1288 					if (err == noErr)
1289 					{
1290 						switch (tHICommand.commandID)
1291 						{
1292 							case 'Clip':
1293 								RomInfoCopyToClipboard();
1294 								result = noErr;
1295 						}
1296 					}
1297 			}
1298 	}
1299 
1300 	return (result);
1301 }
1302 
RegisterHelpBook(void)1303 void RegisterHelpBook (void)
1304 {
1305 	OSStatus	err;
1306 	CFBundleRef	bundleRef;
1307 	CFURLRef	bundleURL;
1308 	FSRef		fref;
1309 
1310 	bundleRef = CFBundleGetMainBundle();
1311 	if (bundleRef)
1312 	{
1313 		bundleURL = CFBundleCopyBundleURL(bundleRef);
1314 		if (bundleURL)
1315 		{
1316 			if (CFURLGetFSRef(bundleURL, &fref))
1317 				err = AHRegisterHelpBook(&fref);
1318 
1319 			CFRelease(bundleURL);
1320 		}
1321 	}
1322 }
1323 
SetHIViewID(HIViewID * cid,OSType signature,SInt32 value)1324 void SetHIViewID (HIViewID *cid, OSType signature, SInt32 value)
1325 {
1326 	// Since HIViewID.id conflicts Objective-C 'id'...
1327 
1328 	cid->signature = signature;
1329 	cid->id = value;
1330 }
1331