/*****************************************************************************\ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. This file is licensed under the Snes9x License. For further information, consult the LICENSE file in the root directory. \*****************************************************************************/ /*********************************************************************************** SNES9X for Mac OS (c) Copyright John Stiles Snes9x for Mac OS X (c) Copyright 2001 - 2011 zones (c) Copyright 2002 - 2005 107 (c) Copyright 2002 PB1400c (c) Copyright 2004 Alexander and Sander (c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2005 Ryan Vogt ***********************************************************************************/ #include "snes9x.h" #include "memmap.h" #include "mac-prefix.h" #include "mac-audio.h" #include "mac-joypad.h" #include "mac-keyboard.h" #include "mac-os.h" #include "mac-render.h" #include "mac-stringtools.h" #include "mac-dialog.h" int autofireLastTabIndex = 1; static int tabList[] = { 2, 257, 258 }; static void RomInfoCopyToClipboard (void); static void RomInfoBuildInfoText (char *); static void AutofireSetAllIconImages (int, HIViewRef); static void AutofireSetIconImages (int, HIViewRef); static void AutofireReadAllSettings (int, HIViewRef); static void AutofireReadSetting (int, uint16, HIViewRef); static void AutofireWriteAllSettings (int, HIViewRef); static void AutofireWriteSetting (int, uint16 *, HIViewRef); static void AutofireSelectTabPane (HIViewRef, SInt16); static OSStatus UpdateTextControlView (HIViewRef); static void AutofireSliderActionProc (HIViewRef, HIViewPartCode); static OSStatus RomInfoEventHandler (EventHandlerCallRef, EventRef, void *); static OSStatus AutofireTabEventHandler (EventHandlerCallRef, EventRef, void *); static OSStatus AutofireWindowEventHandler (EventHandlerCallRef, EventRef, void *); #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 extern "C" FMFont FMGetFontFromATSFontRef (ATSFontRef iFont); #endif static OSStatus UpdateTextControlView (HIViewRef control) { OSStatus err; WindowAttributes attr; err = GetWindowAttributes(GetControlOwner(control), &attr); if (err == noErr) { if (attr & kWindowCompositingAttribute) err = HIViewSetNeedsDisplay(control, true); else Draw1Control(control); } return (err); } OSStatus SetStaticTextCStr (HIViewRef control, char *text, Boolean draw) { OSStatus err; if (!control || !text) return (paramErr); err = SetControlData(control, 0, kControlStaticTextTextTag, strlen(text), text); if ((err == noErr) && draw) err = UpdateTextControlView(control); return (err); } OSStatus SetStaticTextCFString (HIViewRef control, CFStringRef text, Boolean draw) { OSStatus err; if (!control || !text) return (paramErr); err = SetControlData(control, 0, kControlStaticTextCFStringTag, sizeof(CFStringRef), &text); if ((err == noErr) && draw) err = UpdateTextControlView(control); return (err); } OSStatus SetStaticTextTrunc (HIViewRef control, TruncCode mode, Boolean draw) { OSStatus err; TruncCode trunc; Boolean multiline; if (!control) return (paramErr); trunc = mode; multiline = false; err = SetControlData(control, 0, kControlStaticTextIsMultilineTag, sizeof(Boolean), &multiline); if (err == noErr) { err = SetControlData(control, 0, kControlStaticTextTruncTag, sizeof(TruncCode), &trunc); if ((err == noErr) && draw) err = UpdateTextControlView(control); } return (err); } OSStatus GetEditTextCStr (HIViewRef control, char *text) { OSStatus err; Size actualSize; if (!control || !text) return (paramErr); err = GetControlData(control, 0, kControlEditTextTextTag, 255, text, &actualSize); if (err == noErr) text[actualSize] = 0; return (err); } OSStatus SetEditTextCStr (HIViewRef control, char *text, Boolean draw) { OSStatus err; if (!control || !text) return (paramErr); err = SetControlData(control, 0, kControlEditTextTextTag, strlen(text), text); if ((err == noErr) && draw) err = UpdateTextControlView(control); return (err); } OSStatus CopyEditTextCFString (HIViewRef control, CFStringRef *text) { OSStatus err; Size actualSize; if (!control || !text) return (paramErr); err = GetControlData(control, 0, kControlEditTextCFStringTag, sizeof(CFStringRef), text, &actualSize); return (err); } OSStatus SetEditTextCFString (HIViewRef control, CFStringRef text, Boolean draw) { OSStatus err; if (!control || !text) return (paramErr); err = SetControlData(control, 0, kControlEditTextCFStringTag, sizeof(CFStringRef), &text); if ((err == noErr) && draw) err = UpdateTextControlView(control); return (err); } OSStatus SetEditTextSelection (HIViewRef control, SInt16 selStart, SInt16 selEnd) { OSStatus err; ControlEditTextSelectionRec selection; if (!control) return (paramErr); selection.selStart = selStart; selection.selEnd = selEnd; err = SetControlData(control, 0, kControlEditTextSelectionTag, sizeof(selection), &selection); if (err == noErr) err = UpdateTextControlView(control); return (err); } void StartCarbonModalDialog (void) { HiliteMenu(0); if (gWindow) HideWindow(gWindow); } void FinishCarbonModalDialog (void) { if (gWindow) ShowWindow(gWindow); } void MoveWindowPosition (WindowRef window, int which, Boolean resize) { if (savewindowpos) { MoveWindow(window, windowPos[which].h, windowPos[which].v, false); if (resize) { if ((windowSize[which].width > 0) && (windowSize[which].height > 0)) SizeWindow(window, (short) windowSize[which].width, (short) windowSize[which].height, false); } } else RepositionWindow(window, NULL, kWindowAlertPositionOnMainScreen); } void SaveWindowPosition (WindowRef window, int which) { Rect rct; GetWindowBounds(window, kWindowContentRgn, &rct); windowPos[which].h = rct.left; windowPos[which].v = rct.top; windowSize[which].width = (float) (rct.right - rct.left); windowSize[which].height = (float) (rct.bottom - rct.top ); } void AppearanceAlert (AlertType type, int stringID1, int stringID2) { OSStatus err; DialogRef dialog; DialogItemIndex outItemHit; CFStringRef key1, key2, mes1, mes2; char label1[32], label2[32]; sprintf(label1, "AlertMes_%02d", stringID1); sprintf(label2, "AlertMes_%02d", stringID2); key1 = CFStringCreateWithCString(kCFAllocatorDefault, label1, CFStringGetSystemEncoding()); key2 = CFStringCreateWithCString(kCFAllocatorDefault, label2, CFStringGetSystemEncoding()); if (key1) mes1 = CFCopyLocalizedString(key1, "mes1"); else mes1 = NULL; if (key2) mes2 = CFCopyLocalizedString(key2, "mes2"); else mes2 = NULL; NSBeep(); err = CreateStandardAlert(type, mes1, mes2, NULL, &dialog); err = RunStandardAlert(dialog, NULL, &outItemHit); if (key1) CFRelease(key1); if (key2) CFRelease(key2); if (mes1) CFRelease(mes1); if (mes2) CFRelease(mes2); } void AboutDialog (void) { OSStatus err; IBNibRef nibRef; err = CreateNibReference(kMacS9XCFString, &nibRef); if (err == noErr) { WindowRef tWindowRef; err = CreateWindowFromNib(nibRef, CFSTR("About"), &tWindowRef); if (err == noErr) { EventHandlerRef eref; EventHandlerUPP eventUPP; EventTypeSpec windowEvents[] = { { kEventClassWindow, kEventWindowClose }, { kEventClassCommand, kEventCommandUpdateStatus } }; ControlFontStyleRec frec; HIViewRef ctl, root; HIViewID cid; char text[32]; err = ChangeWindowAttributes(tWindowRef, kWindowNoAttributes, kWindowInWindowMenuAttribute); if (systemVersion >= 0x1040) frec.font = FMGetFontFromATSFontRef(ATSFontFindFromName(CFSTR("Lucida Grande"), kATSOptionFlagsDefault)); #ifdef MAC_PANTHER_SUPPORT else frec.font = kThemeSystemFont; #endif frec.just = teCenter; root = HIViewGetRoot(tWindowRef); cid.id = 0; cid.signature = 'VERS'; HIViewFindByID(root, cid, &ctl); sprintf(text, "Version %s (%s)", VERSION, MAC_VERSION); SetStaticTextCStr(ctl, text, false); frec.flags = kControlUseFontMask | kControlUseSizeMask | kControlUseJustMask; frec.size = 10; err = SetControlFontStyle(ctl, &frec); cid.signature = 'NAME'; HIViewFindByID(root, cid, &ctl); frec.flags = kControlUseFontMask | kControlUseSizeMask | kControlUseFaceMask | kControlUseJustMask; frec.size = 14; frec.style = 1; err = SetControlFontStyle(ctl, &frec); eventUPP = NewEventHandlerUPP(DefaultEventHandler); err = InstallWindowEventHandler(tWindowRef, eventUPP, GetEventTypeCount(windowEvents), windowEvents, (void *) tWindowRef, &eref); MoveWindowPosition(tWindowRef, kWindowAbout, false); ShowWindow(tWindowRef); err = RunAppModalLoopForWindow(tWindowRef); HideWindow(tWindowRef); SaveWindowPosition(tWindowRef, kWindowAbout); err = RemoveEventHandler(eref); DisposeEventHandlerUPP(eventUPP); CFRelease(tWindowRef); } DisposeNibReference(nibRef); } } OSStatus DefaultEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) { OSStatus err, result = eventNotHandledErr; WindowRef tWindowRef = (WindowRef) inUserData; switch (GetEventClass(inEvent)) { case kEventClassWindow: switch (GetEventKind(inEvent)) { case kEventWindowClose: QuitAppModalLoopForWindow(tWindowRef); result = noErr; } break; case kEventClassCommand: switch (GetEventKind(inEvent)) { case kEventCommandUpdateStatus: HICommand tHICommand; err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand); if (err == noErr && tHICommand.commandID == 'clos') { UpdateMenuCommandStatus(true); result = noErr; } } break; } return (result); } void ConfigureAutofire (void) { OSStatus err; IBNibRef nibRef; err = CreateNibReference(kMacS9XCFString, &nibRef); if (err == noErr) { WindowRef tWindowRef; err = CreateWindowFromNib(nibRef, CFSTR("AutoFire"), &tWindowRef); if (err == noErr) { EventHandlerRef wRef, tRef; EventHandlerUPP wUPP, tUPP; EventTypeSpec wEvent[] = { { kEventClassWindow, kEventWindowClose }, { kEventClassCommand, kEventCommandProcess }, { kEventClassCommand, kEventCommandUpdateStatus } }, tEvent[] = { { kEventClassControl, kEventControlHit } }; ControlActionUPP actionUPP; HIViewRef ctl, root; HIViewID cid; root = HIViewGetRoot(tWindowRef); wUPP = NewEventHandlerUPP(AutofireWindowEventHandler); err = InstallWindowEventHandler(tWindowRef, wUPP, GetEventTypeCount(wEvent), wEvent, (void *) tWindowRef, &wRef); cid.signature = 'Ftab'; cid.id = 256; HIViewFindByID(root, cid, &ctl); SetControl32BitValue(ctl, autofireLastTabIndex); AutofireSelectTabPane(ctl, autofireLastTabIndex); tUPP = NewEventHandlerUPP(AutofireTabEventHandler); err = InstallControlEventHandler(ctl, tUPP, GetEventTypeCount(tEvent), tEvent, 0, &tRef); actionUPP = NewControlActionUPP(AutofireSliderActionProc); for (int player = 0; player < 2; player++) { AutofireSetAllIconImages(player + 1, root); AutofireReadAllSettings(player + 1, root); cid.id = player + 1; cid.signature = 'Slid'; HIViewFindByID(root, cid, &ctl); SetControlAction(ctl, actionUPP); } MoveWindowPosition(tWindowRef, kWindowAutoFire, false); ShowWindow(tWindowRef); err = RunAppModalLoopForWindow(tWindowRef); HideWindow(tWindowRef); SaveWindowPosition(tWindowRef, kWindowAutoFire); for (int player = 0; player < 2; player++) AutofireWriteAllSettings(player + 1, root); autofire = (autofireRec[0].buttonMask || autofireRec[1].buttonMask) ? true : false; err = RemoveEventHandler(tRef); DisposeEventHandlerUPP(tUPP); err = RemoveEventHandler(wRef); DisposeEventHandlerUPP(wUPP); DisposeControlActionUPP(actionUPP); CFRelease(tWindowRef); } DisposeNibReference(nibRef); } } static void AutofireSetAllIconImages (int player, HIViewRef parent) { AutofireSetIconImages(player * 1, parent); AutofireSetIconImages(player * 11, parent); AutofireSetIconImages(player * 111, parent); AutofireSetIconImages(player * 1111, parent); } static void AutofireSetIconImages (int sig, HIViewRef parent) { OSStatus err; ControlButtonContentInfo info; HIViewRef ctl; HIViewID cid; int ofs; cid.id = sig; ofs = macPadIconIndex + ((sig % 2) ? 0 : 12); if (systemVersion >= 0x1040) { info.contentType = kControlContentCGImageRef; cid.signature = 'AChk'; HIViewFindByID(parent, cid, &ctl); info.u.imageRef = macIconImage[7 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'BChk'; HIViewFindByID(parent, cid, &ctl); info.u.imageRef = macIconImage[5 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'XChk'; HIViewFindByID(parent, cid, &ctl); info.u.imageRef = macIconImage[6 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'YChk'; HIViewFindByID(parent, cid, &ctl); info.u.imageRef = macIconImage[4 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'LChk'; HIViewFindByID(parent, cid, &ctl); info.u.imageRef = macIconImage[8 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'RChk'; HIViewFindByID(parent, cid, &ctl); info.u.imageRef = macIconImage[9 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'Up '; HIViewFindByID(parent, cid, &ctl); info.u.imageRef = macIconImage[0 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'Down'; HIViewFindByID(parent, cid, &ctl); info.u.imageRef = macIconImage[1 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'Left'; HIViewFindByID(parent, cid, &ctl); info.u.imageRef = macIconImage[2 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'Righ'; HIViewFindByID(parent, cid, &ctl); info.u.imageRef = macIconImage[3 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'Star'; HIViewFindByID(parent, cid, &ctl); info.u.imageRef = macIconImage[10 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'Sele'; HIViewFindByID(parent, cid, &ctl); info.u.imageRef = macIconImage[11 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); } #ifdef MAC_PANTHER_SUPPORT else { info.contentType = kControlContentIconRef; cid.signature = 'AChk'; HIViewFindByID(parent, cid, &ctl); info.u.iconRef = macIconRef[7 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'BChk'; HIViewFindByID(parent, cid, &ctl); info.u.iconRef = macIconRef[5 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'XChk'; HIViewFindByID(parent, cid, &ctl); info.u.iconRef = macIconRef[6 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'YChk'; HIViewFindByID(parent, cid, &ctl); info.u.iconRef = macIconRef[4 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'LChk'; HIViewFindByID(parent, cid, &ctl); info.u.iconRef = macIconRef[8 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'RChk'; HIViewFindByID(parent, cid, &ctl); info.u.iconRef = macIconRef[9 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'Up '; HIViewFindByID(parent, cid, &ctl); info.u.iconRef = macIconRef[0 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'Down'; HIViewFindByID(parent, cid, &ctl); info.u.iconRef = macIconRef[1 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'Left'; HIViewFindByID(parent, cid, &ctl); info.u.iconRef = macIconRef[2 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'Righ'; HIViewFindByID(parent, cid, &ctl); info.u.iconRef = macIconRef[3 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'Star'; HIViewFindByID(parent, cid, &ctl); info.u.iconRef = macIconRef[10 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); cid.signature = 'Sele'; HIViewFindByID(parent, cid, &ctl); info.u.iconRef = macIconRef[11 + ofs]; err = SetBevelButtonContentInfo(ctl, &info); } #endif } static void AutofireReadAllSettings (int player, HIViewRef parent) { HIViewRef ctl; HIViewID cid; char num[10]; AutofireReadSetting(player * 1, autofireRec[player - 1].buttonMask, parent); AutofireReadSetting(player * 11, autofireRec[player - 1].toggleMask, parent); AutofireReadSetting(player * 111, autofireRec[player - 1].tcMask, parent); AutofireReadSetting(player * 1111, autofireRec[player - 1].invertMask, parent); cid.id = player; cid.signature = 'Num_'; HIViewFindByID(parent, cid, &ctl); sprintf(num, "%ld", autofireRec[player - 1].frequency); SetStaticTextCStr(ctl, num, false); cid.signature = 'Slid'; HIViewFindByID(parent, cid, &ctl); SetControl32BitValue(ctl, autofireRec[player - 1].frequency); } static void AutofireReadSetting (int sig, uint16 target, HIViewRef parent) { HIViewRef ctl; HIViewID cid; cid.id = sig; cid.signature = 'AChk'; HIViewFindByID(parent, cid, &ctl); SetControl32BitValue(ctl, (target & 0x0080) ? 1 : 0); cid.signature = 'BChk'; HIViewFindByID(parent, cid, &ctl); SetControl32BitValue(ctl, (target & 0x8000) ? 1 : 0); cid.signature = 'XChk'; HIViewFindByID(parent, cid, &ctl); SetControl32BitValue(ctl, (target & 0x0040) ? 1 : 0); cid.signature = 'YChk'; HIViewFindByID(parent, cid, &ctl); SetControl32BitValue(ctl, (target & 0x4000) ? 1 : 0); cid.signature = 'LChk'; HIViewFindByID(parent, cid, &ctl); SetControl32BitValue(ctl, (target & 0x0020) ? 1 : 0); cid.signature = 'RChk'; HIViewFindByID(parent, cid, &ctl); SetControl32BitValue(ctl, (target & 0x0010) ? 1 : 0); cid.signature = 'Up '; HIViewFindByID(parent, cid, &ctl); SetControl32BitValue(ctl, (target & 0x0800) ? 1 : 0); cid.signature = 'Down'; HIViewFindByID(parent, cid, &ctl); SetControl32BitValue(ctl, (target & 0x0400) ? 1 : 0); cid.signature = 'Left'; HIViewFindByID(parent, cid, &ctl); SetControl32BitValue(ctl, (target & 0x0200) ? 1 : 0); cid.signature = 'Righ'; HIViewFindByID(parent, cid, &ctl); SetControl32BitValue(ctl, (target & 0x0100) ? 1 : 0); cid.signature = 'Star'; HIViewFindByID(parent, cid, &ctl); SetControl32BitValue(ctl, (target & 0x1000) ? 1 : 0); cid.signature = 'Sele'; HIViewFindByID(parent, cid, &ctl); SetControl32BitValue(ctl, (target & 0x2000) ? 1 : 0); } static void AutofireWriteAllSettings (int player, HIViewRef parent) { HIViewRef ctl; HIViewID cid; AutofireWriteSetting(player * 1, &(autofireRec[player - 1].buttonMask), parent); AutofireWriteSetting(player * 11, &(autofireRec[player - 1].toggleMask), parent); AutofireWriteSetting(player * 111, &(autofireRec[player - 1].tcMask), parent); AutofireWriteSetting(player * 1111, &(autofireRec[player - 1].invertMask), parent); cid.id = player; cid.signature = 'Slid'; HIViewFindByID(parent, cid, &ctl); autofireRec[player - 1].frequency = GetControl32BitValue(ctl); } static void AutofireWriteSetting (int sig, uint16 *target, HIViewRef parent) { HIViewRef ctl; HIViewID cid; cid.id = sig; *target = 0x0000; cid.signature = 'AChk'; HIViewFindByID(parent, cid, &ctl); if (GetControl32BitValue(ctl)) (*target) |= 0x0080; cid.signature = 'BChk'; HIViewFindByID(parent, cid, &ctl); if (GetControl32BitValue(ctl)) (*target) |= 0x8000; cid.signature = 'XChk'; HIViewFindByID(parent, cid, &ctl); if (GetControl32BitValue(ctl)) (*target) |= 0x0040; cid.signature = 'YChk'; HIViewFindByID(parent, cid, &ctl); if (GetControl32BitValue(ctl)) (*target) |= 0x4000; cid.signature = 'LChk'; HIViewFindByID(parent, cid, &ctl); if (GetControl32BitValue(ctl)) (*target) |= 0x0020; cid.signature = 'RChk'; HIViewFindByID(parent, cid, &ctl); if (GetControl32BitValue(ctl)) (*target) |= 0x0010; cid.signature = 'Up '; HIViewFindByID(parent, cid, &ctl); if (GetControl32BitValue(ctl)) (*target) |= 0x0800; cid.signature = 'Down'; HIViewFindByID(parent, cid, &ctl); if (GetControl32BitValue(ctl)) (*target) |= 0x0400; cid.signature = 'Left'; HIViewFindByID(parent, cid, &ctl); if (GetControl32BitValue(ctl)) (*target) |= 0x0200; cid.signature = 'Righ'; HIViewFindByID(parent, cid, &ctl); if (GetControl32BitValue(ctl)) (*target) |= 0x0100; cid.signature = 'Star'; HIViewFindByID(parent, cid, &ctl); if (GetControl32BitValue(ctl)) (*target) |= 0x1000; cid.signature = 'Sele'; HIViewFindByID(parent, cid, &ctl); if (GetControl32BitValue(ctl)) (*target) |= 0x2000; } static void AutofireSelectTabPane (HIViewRef tabControl, SInt16 index) { HIViewRef sup, userPane, selectedPane = NULL; HIViewID cid; autofireLastTabIndex = index; sup = HIViewGetSuperview(tabControl); cid.signature = 'Ftab'; for (int i = 1; i < tabList[0] + 1; i++) { cid.id = tabList[i]; HIViewFindByID(sup, cid, &userPane); if (i == index) selectedPane = userPane; else HIViewSetVisible(userPane, false); } if (selectedPane != NULL) HIViewSetVisible(selectedPane, true); HIViewSetNeedsDisplay(tabControl, true); } static OSStatus AutofireTabEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) { OSStatus err, result = eventNotHandledErr; HIViewRef ctl; HIViewID cid; SInt32 value; err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &ctl); if (err == noErr) { GetControlID(ctl, &cid); value = GetControl32BitValue(ctl); if ((cid.id == 256) && (value != autofireLastTabIndex)) { AutofireSelectTabPane(ctl, value); result = noErr; } } return (result); } static OSStatus AutofireWindowEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) { OSStatus err, result = eventNotHandledErr; WindowRef tWindowRef = (WindowRef) inUserData; switch (GetEventClass(inEvent)) { case kEventClassWindow: switch (GetEventKind(inEvent)) { case kEventWindowClose: QuitAppModalLoopForWindow(tWindowRef); result = noErr; } break; case kEventClassCommand: switch (GetEventKind(inEvent)) { HICommand tHICommand; case kEventCommandUpdateStatus: err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand); if (err == noErr && tHICommand.commandID == 'clos') { UpdateMenuCommandStatus(true); result = noErr; } break; case kEventCommandProcess: HIViewRef root; int player = -1; root = HIViewGetRoot(tWindowRef); err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand); if (err == noErr) { switch (tHICommand.commandID) { case 'DEF1': player = 0; break; case 'DEF2': player = 1; break; } if (player != -1) { autofireRec[player].buttonMask = 0x0000; autofireRec[player].toggleMask = 0xFFF0; autofireRec[player].tcMask = 0x0000; autofireRec[player].invertMask = 0x0000; autofireRec[player].frequency = 10; AutofireReadAllSettings(player + 1, root); result = noErr; } } } } return (result); } static void AutofireSliderActionProc (HIViewRef slider, HIViewPartCode partCode) { HIViewRef ctl; HIViewID cid; char num[10]; GetControlID(slider, &cid); cid.signature = 'Num_'; HIViewFindByID(HIViewGetSuperview(slider), cid, &ctl); sprintf(num, "%ld", GetControl32BitValue(slider)); SetStaticTextCStr(ctl, num, true); } void RomInfoDialog (void) { OSStatus err; IBNibRef nibRef; if (!cartOpen) return; err = CreateNibReference(kMacS9XCFString, &nibRef); if (err == noErr) { WindowRef tWindowRef; err = CreateWindowFromNib(nibRef, CFSTR("RomInfo"), &tWindowRef); if (err == noErr) { EventHandlerRef eref; EventHandlerUPP eventUPP; EventTypeSpec windowEvents[] = { { kEventClassWindow, kEventWindowClose }, { kEventClassCommand, kEventCommandProcess }, { kEventClassCommand, kEventCommandUpdateStatus } }; CFStringRef sref; HIViewRef ctl, root; HIViewID cid; char text[256]; eventUPP = NewEventHandlerUPP(RomInfoEventHandler); err = InstallWindowEventHandler(tWindowRef, eventUPP, GetEventTypeCount(windowEvents), windowEvents, (void *) tWindowRef, &eref); root = HIViewGetRoot(tWindowRef); cid.id = 0; cid.signature = 'Name'; // Cart Name HIViewFindByID(root, cid, &ctl); strcpy(text, Memory.RawROMName); sref = CopyFixNameStrings(text, Memory.ROMRegion); if (!sref) SetStaticTextCFString(ctl, CFSTR("unknown"), false); else { SetStaticTextCFString(ctl, sref, false); CFRelease(sref); } cid.signature = 'Code'; // Game Code HIViewFindByID(root, cid, &ctl); sprintf(text, "%s", Memory.ROMId); SetStaticTextCStr(ctl, text, false); cid.signature = 'Cont'; // Contents HIViewFindByID(root, cid, &ctl); sprintf(text, "%s", Memory.KartContents()); SetStaticTextCStr(ctl, text, false); cid.signature = 'Map '; // ROM Map HIViewFindByID(root, cid, &ctl); sprintf(text, "%s", Memory.MapType()); SetStaticTextCStr(ctl, text, false); cid.signature = 'Spee'; // ROM Speed HIViewFindByID(root, cid, &ctl); sprintf(text, "0x%02X (%s)", Memory.ROMSpeed, ((Memory.ROMSpeed & 0x10) != 0) ? "FastROM" : "SlowROM"); SetStaticTextCStr(ctl, text, false); cid.signature = 'Type'; // ROM Type HIViewFindByID(root, cid, &ctl); sprintf(text, "0x%02X", Memory.ROMType); SetStaticTextCStr(ctl, text, false); cid.signature = 'SizC'; // Actual ROM Size HIViewFindByID(root, cid, &ctl); sprintf(text, "%dMbits", Memory.CalculatedSize / 0x20000); SetStaticTextCStr(ctl, text, false); cid.signature = 'SizH'; // ROM Size written in info block HIViewFindByID(root, cid, &ctl); sprintf(text, "%s", Memory.Size()); SetStaticTextCStr(ctl, text, false); cid.signature = 'SRAM'; // SRAM Size HIViewFindByID(root, cid, &ctl); sprintf(text, "%s", Memory.StaticRAMSize()); SetStaticTextCStr(ctl, text, false); cid.signature = 'SumC'; // Actual checksum HIViewFindByID(root, cid, &ctl); sprintf(text, "0x%04X", Memory.CalculatedChecksum); SetStaticTextCStr(ctl, text, false); cid.signature = 'SumH'; // Checksum written in info block HIViewFindByID(root, cid, &ctl); sprintf(text, "0x%04X", Memory.ROMChecksum); SetStaticTextCStr(ctl, text, false); cid.signature = 'ComH'; // Checksum complement written in info block : SumH + ComH = 0xFFFF HIViewFindByID(root, cid, &ctl); sprintf(text, "0x%04X", Memory.ROMComplementChecksum); SetStaticTextCStr(ctl, text, false); cid.signature = 'Outp'; // Video output (NTSC or PAL) HIViewFindByID(root, cid, &ctl); sprintf(text, "%s", (Memory.ROMRegion > 12 || Memory.ROMRegion < 2) ? "NTSC 60Hz" : "PAL 50Hz"); SetStaticTextCStr(ctl, text, false); cid.signature = 'Vers'; // Revision HIViewFindByID(root, cid, &ctl); sprintf(text, "%s", Memory.Revision()); SetStaticTextCStr(ctl, text, false); cid.signature = 'Lice'; // Licensee HIViewFindByID(root, cid, &ctl); sprintf(text, "%s", Memory.PublishingCompany()); SetStaticTextCStr(ctl, text, false); cid.signature = 'Regi'; // Region HIViewFindByID(root, cid, &ctl); sprintf(text, "%s", Memory.Country()); SetStaticTextCStr(ctl, text, false); cid.signature = 'CRC '; // CRC32 HIViewFindByID(root, cid, &ctl); sprintf(text, "0x%08X", Memory.ROMCRC32); SetStaticTextCStr(ctl, text, false); MoveWindowPosition(tWindowRef, kWindowRomInfo, false); ShowWindow(tWindowRef); err = RunAppModalLoopForWindow(tWindowRef); HideWindow(tWindowRef); SaveWindowPosition(tWindowRef, kWindowRomInfo); err = RemoveEventHandler(eref); DisposeEventHandlerUPP(eventUPP); CFRelease(tWindowRef); } DisposeNibReference(nibRef); } } static void RomInfoCopyToClipboard (void) { OSStatus err; PasteboardRef clipboard; PasteboardSyncFlags sync; CFDataRef cfdata; char text[1024]; RomInfoBuildInfoText(text); err = PasteboardCreate(kPasteboardClipboard, &clipboard); if (err == noErr) { err = PasteboardClear(clipboard); if (err == noErr) { sync = PasteboardSynchronize(clipboard); if (!(sync & kPasteboardModified) && (sync & kPasteboardClientIsOwner)) { cfdata = CFDataCreate(kCFAllocatorDefault, (UInt8 *) text, (CFIndex) strlen(text)); if (cfdata) { err = PasteboardPutItemFlavor(clipboard, (PasteboardItemID) 1, CFSTR("com.apple.traditional-mac-plain-text"), cfdata, 0); CFRelease(cfdata); } } } CFRelease(clipboard); } } static void RomInfoBuildInfoText (char *romtext) { char s1[256], s2[1024]; sprintf(s1, "Snes9x version: %s\nMac port version: %s, ", VERSION, MAC_VERSION); #ifdef __BIG_ENDIAN__ strcat(s1, "PowerPC\n\n"); #else strcat(s1, "Intel\n\n"); #endif Memory.MakeRomInfoText(s2); sprintf(romtext, "%s%s", s1, s2); } static OSStatus RomInfoEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) { OSStatus err, result = eventNotHandledErr; WindowRef tWindowRef = (WindowRef) inUserData; switch (GetEventClass(inEvent)) { case kEventClassWindow: switch (GetEventKind(inEvent)) { case kEventWindowClose: QuitAppModalLoopForWindow(tWindowRef); result = noErr; } break; case kEventClassCommand: switch (GetEventKind(inEvent)) { HICommand tHICommand; case kEventCommandUpdateStatus: err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand); if (err == noErr && tHICommand.commandID == 'clos') { UpdateMenuCommandStatus(true); result = noErr; } break; case kEventCommandProcess: err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand); if (err == noErr) { switch (tHICommand.commandID) { case 'Clip': RomInfoCopyToClipboard(); result = noErr; } } } } return (result); } void RegisterHelpBook (void) { OSStatus err; CFBundleRef bundleRef; CFURLRef bundleURL; FSRef fref; bundleRef = CFBundleGetMainBundle(); if (bundleRef) { bundleURL = CFBundleCopyBundleURL(bundleRef); if (bundleURL) { if (CFURLGetFSRef(bundleURL, &fref)) err = AHRegisterHelpBook(&fref); CFRelease(bundleURL); } } } void SetHIViewID (HIViewID *cid, OSType signature, SInt32 value) { // Since HIViewID.id conflicts Objective-C 'id'... cid->signature = signature; cid->id = value; }