/********************************************************************************** Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com), Jerremy Koot (jkoot@snes9x.com) (c) Copyright 2002 - 2004 Matthew Kendora (c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org) (c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/) (c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net) (c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca), Kris Bleakley (codeviolation@hotmail.com) (c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, zones C4 x86 assembler and some C emulation code (c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com), Nach, zsKnight (zsknight@zsnes.com) C4 C++ code (c) Copyright 2003 - 2006 Brad Jorsch, Nach DSP-1 emulator code (c) Copyright 1998 - 2006 _Demo_, Andreas Naive (andreasnaive@gmail.com) Gary Henderson, Ivar (ivar@snes9x.com), John Weidman, Kris Bleakley, Matthew Kendora, Nach, neviksti (neviksti@hotmail.com) DSP-2 emulator code (c) Copyright 2003 John Weidman, Kris Bleakley, Lord Nightmare (lord_nightmare@users.sourceforge.net), Matthew Kendora, neviksti DSP-3 emulator code (c) Copyright 2003 - 2006 John Weidman, Kris Bleakley, Lancer, z80 gaiden DSP-4 emulator code (c) Copyright 2004 - 2006 Dreamer Nom, John Weidman, Kris Bleakley, Nach, z80 gaiden OBC1 emulator code (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com), Kris Bleakley, Ported from x86 assembler to C by sanmaiwashi SPC7110 and RTC C++ emulator code (c) Copyright 2002 Matthew Kendora with research by zsKnight, John Weidman, Dark Force S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive, John Weidman S-RTC C emulator code (c) Copyright 2001-2006 byuu, John Weidman ST010 C++ emulator code (c) Copyright 2003 Feather, John Weidman, Kris Bleakley, Matthew Kendora Super FX x86 assembler emulator code (c) Copyright 1998 - 2003 _Demo_, pagefault, zsKnight, Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson, John Weidman Sound DSP emulator code is derived from SNEeSe and OpenSPC: (c) Copyright 1998 - 2003 Brad Martin (c) Copyright 1998 - 2006 Charles Bilyue' SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) 2xSaI filter (c) Copyright 1999 - 2001 Derek Liauw Kie Fa HQ2x, HQ3x, HQ4x filters (c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com) Win32 GUI code (c) Copyright 2003 - 2006 blip, funkyass, Matthew Kendora, Nach, nitsuja Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles (c) Copyright 2001 - 2007 zones Specific ports contains the works of other authors. See headers in individual files. Snes9x homepage: http://www.snes9x.com Permission to use, copy, modify and/or distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software or it's derivatives. Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes, but is not limited to, charging money for Snes9x or software derived from Snes9x, including Snes9x or derivatives in commercial game bundles, and/or using Snes9x as a promotion for your commercial product. The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. **********************************************************************************/ /********************************************************************************** SNES9X for Mac OS (c) Copyright John Stiles Snes9x for Mac OS X (c) Copyright 2001 - 2007 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 "memmap.h" #include "mac-prefix.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 void RomInfoCopyToClipboard(void); static void RomInfoBuildInfoText(char *); static void RomInfoGetLicenseeText(char *); static void RomInfoGetRegionText(char *); 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 char *StaticRAMBitSize(void); static OSStatus UpdateTextControlView(HIViewRef); static pascal void AutofireSliderActionProc(HIViewRef, HIViewPartCode); static pascal OSStatus RomInfoEventHandler(EventHandlerCallRef, EventRef, void *); static pascal OSStatus AutofireTabEventHandler(EventHandlerCallRef, EventRef, void *); static pascal OSStatus AutofireWindowEventHandler(EventHandlerCallRef, EventRef, void *); static int tabList[] = { 2, 257, 258 }; 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 GetStaticTextText(HIViewRef control, Str255 text) { OSStatus err; Size actualSize; if ((!control) || (!text)) return paramErr; err = GetControlData(control, 0, kControlStaticTextTextTag, 255, (Ptr) (text + 1), &actualSize); if (err == noErr) text[0] = (actualSize > 255) ? 255 : actualSize; return err; } OSStatus SetStaticTextText(HIViewRef control, Str255 text, Boolean draw) { OSStatus err; if ((!control) || (!text)) return paramErr; err = SetControlData(control, 0, kControlStaticTextTextTag, text[0], (Ptr) (text + 1)); 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 SetStaticTextCFString(HIViewRef control, CFStringRef text, Boolean draw) { OSStatus err; if ((!control) || (!text)) return paramErr; err = SetControlData(control, 0, kControlStaticTextCFStringTag, sizeof(CFStringRef), (Ptr) &text); if ((err == noErr) && draw) err = UpdateTextControlView(control); return err; } OSStatus SetEditTextCFString(HIViewRef control, CFStringRef text, Boolean draw) { OSStatus err; if ((!control) || (!text)) return paramErr; err = SetControlData(control, 0, kControlEditTextCFStringTag, sizeof(CFStringRef), (Ptr) &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), (Ptr) text, &actualSize); return err; } OSStatus GetEditTextText(HIViewRef control, Str255 text) { OSStatus err; Size actualSize; if ((!control) || (!text)) return paramErr; err = GetControlData(control, 0, kControlEditTextTextTag, 255, (Ptr) (text + 1), &actualSize); if (err == noErr) text[0] = (actualSize > 255) ? 255 : actualSize; return err; } OSStatus SetEditTextText(HIViewRef control, Str255 text, Boolean draw) { OSStatus err; if ((!control) || (!text)) return paramErr; err = SetControlData(control, 0, kControlEditTextTextTag, text[0], (Ptr) (text + 1)); 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), (Ptr) &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, nil, 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 = nil; if (key2) mes2 = CFCopyLocalizedString(key2, "mes2"); else mes2 = nil; SysBeep(10); err = CreateStandardAlert(type, mes1, mes2, nil, &dialog); err = RunStandardAlert(dialog, nil, &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]; unsigned char textP[32]; err = ChangeWindowAttributes(tWindowRef, kWindowNoAttributes, kWindowInWindowMenuAttribute); if (systemVersion >= 0x1040) frec.font = FMGetFontFromATSFontRef(ATSFontFindFromName(CFSTR("Lucida Grande"), kATSOptionFlagsDefault)); #ifdef MAC_PANTHER_JAGUAR_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); ConvertCString(text, textP); SetStaticTextText(ctl, textP, 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); ReleaseWindow(tWindowRef); } DisposeNibReference(nibRef); } } pascal OSStatus DefaultEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) { #pragma unused (inHandlerRef) 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, nil, sizeof(HICommand), nil, &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; int player; 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 (player = 0; player < 2; player++) { 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 (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); ReleaseWindow(tWindowRef); } DisposeNibReference(nibRef); } } static void AutofireReadAllSettings(int player, HIViewRef parent) { HIViewRef ctl; HIViewID cid; char num[10]; unsigned char numP[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_'; sprintf(num, "%ld", autofireRec[player - 1].frequency); ConvertCString(num, numP); HIViewFindByID(parent, cid, &ctl); SetStaticTextText(ctl, numP, 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 = nil; 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 != nil) HIViewSetVisible(selectedPane, true); HIViewSetNeedsDisplay(tabControl, true); } static pascal OSStatus AutofireTabEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) { #pragma unused (inHandlerRef, inUserData) OSStatus result = eventNotHandledErr; HIViewRef ctl; HIViewID cid; SInt32 value; GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, nil, sizeof(ControlRef), nil, &ctl); GetControlID(ctl, &cid); value = GetControl32BitValue(ctl); if ((cid.id == 256) && (value != autofireLastTabIndex)) { AutofireSelectTabPane(ctl, value); result = noErr; } return result; } static pascal OSStatus AutofireWindowEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) { #pragma unused (inHandlerRef) 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, nil, sizeof(HICommand), nil, &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, nil, sizeof(HICommand), nil, &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 pascal void AutofireSliderActionProc(HIViewRef slider, HIViewPartCode partCode) { #pragma unused (partCode) HIViewRef ctl; HIViewID cid; char num[10]; unsigned char numP[10]; GetControlID(slider, &cid); cid.signature = 'Num_'; HIViewFindByID(HIViewGetSuperview(slider), cid, &ctl); sprintf(num, "%ld", GetControl32BitValue(slider)); ConvertCString(num, numP); SetStaticTextText(ctl, numP, 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]; unsigned char textP[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); sprintf(text, "%s", Memory.RawROMName); sref = CopyFixNameStrings(text, Memory.ROMRegion); if (!sref) SetStaticTextCFString(ctl, CFSTR("unknown"), false); else { SetStaticTextCFString(ctl, sref, false); CFRelease(sref); } cid.signature = 'Spee'; // ROM Speed HIViewFindByID(root, cid, &ctl); sprintf(text, "0x%02X/%s", Memory.ROMSpeed, ((Memory.ROMSpeed & 0x10) != 0) ? "FastROM" : "SlowROM"); ConvertCString(text, textP); SetStaticTextText(ctl, textP, false); cid.signature = 'Map '; // ROM Map HIViewFindByID(root, cid, &ctl); sprintf(text, "%s", Memory.MapType()); ConvertCString(text, textP); SetStaticTextText(ctl, textP, false); cid.signature = 'Type'; // ROM Type HIViewFindByID(root, cid, &ctl); sprintf(text, "0x%02X", Memory.ROMType); ConvertCString(text, textP); SetStaticTextText(ctl, textP, false); cid.signature = 'Cont'; // Contents HIViewFindByID(root, cid, &ctl); sprintf(text, "%s", Memory.KartContents()); ConvertCString(text, textP); SetStaticTextText(ctl, textP, false); cid.signature = 'SizH'; // ROM Size written in info block HIViewFindByID(root, cid, &ctl); sprintf(text, "%s", Memory.Size()); ConvertCString(text, textP); SetStaticTextText(ctl, textP, false); cid.signature = 'SizC'; // Actual ROM Size HIViewFindByID(root, cid, &ctl); sprintf(text, "%dMbits", Memory.CalculatedSize / 0x20000); ConvertCString(text, textP); SetStaticTextText(ctl, textP, false); cid.signature = 'SRAM'; // SRAM Size HIViewFindByID(root, cid, &ctl); sprintf(text, "%s%s", Memory.StaticRAMSize(), StaticRAMBitSize()); ConvertCString(text, textP); SetStaticTextText(ctl, textP, false); cid.signature = 'SumC'; // Actual checksum HIViewFindByID(root, cid, &ctl); sprintf(text, "0x%04X", Memory.CalculatedChecksum); ConvertCString(text, textP); SetStaticTextText(ctl, textP, false); cid.signature = 'SumH'; // Checksum written in info block HIViewFindByID(root, cid, &ctl); sprintf(text, "0x%04X", Memory.ROMChecksum); ConvertCString(text, textP); SetStaticTextText(ctl, textP, false); cid.signature = 'ComH'; // Checksum complement written in info block : SumH + ComH = 0xFFFF HIViewFindByID(root, cid, &ctl); sprintf(text, "0x%04X", Memory.ROMComplementChecksum); ConvertCString(text, textP); SetStaticTextText(ctl, textP, false); cid.signature = 'CRC '; // CRC32 HIViewFindByID(root, cid, &ctl); sprintf(text, "0x%08X", Memory.ROMCRC32); ConvertCString(text, textP); SetStaticTextText(ctl, textP, false); cid.signature = 'Outp'; // Output (NTSC or PAL) HIViewFindByID(root, cid, &ctl); sprintf(text, "%s", (Memory.ROMRegion > 12 || Memory.ROMRegion < 2) ? "NTSC 60Hz" : "PAL 50Hz"); ConvertCString(text, textP); SetStaticTextText(ctl, textP, false); cid.signature = 'Vers'; // Revision HIViewFindByID(root, cid, &ctl); sprintf(text, "%s", Memory.Revision()); ConvertCString(text, textP); SetStaticTextText(ctl, textP, false); cid.signature = 'Lice'; // Licensee HIViewFindByID(root, cid, &ctl); RomInfoGetLicenseeText(text); ConvertCString(text, textP); SetStaticTextText(ctl, textP, false); cid.signature = 'Regi'; // Region HIViewFindByID(root, cid, &ctl); RomInfoGetRegionText(text); ConvertCString(text, textP); SetStaticTextText(ctl, textP, false); MoveWindowPosition(tWindowRef, kWindowRomInfo, false); ShowWindow(tWindowRef); err = RunAppModalLoopForWindow(tWindowRef); HideWindow(tWindowRef); SaveWindowPosition(tWindowRef, kWindowRomInfo); err = RemoveEventHandler(eref); DisposeEventHandlerUPP(eventUPP); ReleaseWindow(tWindowRef); } DisposeNibReference(nibRef); } } static void RomInfoCopyToClipboard(void) { OSStatus err; char text[2048]; RomInfoBuildInfoText(text); err = ClearCurrentScrap(); if (err == noErr) { ScrapRef scrap; err = GetCurrentScrap(&scrap); if (err == noErr) err = PutScrapFlavor(scrap, kScrapFlavorTypeText, kScrapFlavorMaskNone, strlen(text), text); } } static void RomInfoBuildInfoText(char *romtext) { char temp[256]; sprintf(romtext, "Snes9x version: %s\n", VERSION); sprintf(temp, "Mac port version: %s, OS X\n\n", MAC_VERSION); strcat (romtext, temp); sprintf(temp, "Name: %s\n", Memory.ROMName); strcat (romtext, temp); sprintf(temp, "Speed: %02X/%s\n", Memory.ROMSpeed, ((Memory.ROMSpeed & 0x10) !=0) ? "FastROM" : "SlowROM"); strcat (romtext, temp); sprintf(temp, "Map: %s\n", Memory.MapType()); strcat (romtext, temp); sprintf(temp, "Type: %02X\n", Memory.ROMType); strcat (romtext, temp); strcat (romtext, "Kart contents: "); strcat (romtext, Memory.KartContents()); strcat (romtext, "\nHeader ROM Size: "); strcat (romtext, Memory.Size()); sprintf(temp, "\nCalculated ROM Size: %dMbits", Memory.CalculatedSize / 0x20000); strcat (romtext, temp); strcat (romtext, "\nSRAM size: "); strcat (romtext, Memory.StaticRAMSize()); strcat (romtext, StaticRAMBitSize()); strcat (romtext, "\nActual Checksum: "); sprintf(temp, "%04X", Memory.CalculatedChecksum); strcat (romtext, temp); strcat (romtext, "\nHeader Checksum: "); sprintf(temp, "%04X", Memory.ROMChecksum); strcat (romtext, temp); strcat (romtext, "\nHeader Checksum Complement: "); sprintf(temp, "%04X", Memory.ROMComplementChecksum); strcat (romtext, temp); strcat (romtext, "\nOutput: "); if (Memory.ROMRegion > 12 || Memory.ROMRegion < 2) strcat(romtext, "NTSC 60Hz"); else strcat(romtext, "PAL 50Hz"); sprintf(temp, "\nCRC32: %08X", Memory.ROMCRC32); strcat (romtext, temp); strcat (romtext, "\nLicensee: "); RomInfoGetLicenseeText(temp); strcat (romtext, temp); strcat (romtext, "\nRevision: "); strcat (romtext, Memory.Revision()); strcat (romtext, "\nRegion: "); RomInfoGetRegionText(temp); strcat (romtext, temp); } #define NOTKNOWN "Unknown Company " static void RomInfoGetLicenseeText(char *text) { int tmp = -1; if (Memory.CompanyId[0] == '0') tmp = 0; if (Memory.CompanyId[0] == '1') tmp = 16; if (Memory.CompanyId[0] == '2') tmp = 32; if (Memory.CompanyId[0] == '3') tmp = 48; if (Memory.CompanyId[0] == '4') tmp = 64; if (Memory.CompanyId[0] == '5') tmp = 80; if (Memory.CompanyId[0] == '6') tmp = 96; if (Memory.CompanyId[0] == '7') tmp = 112; if (Memory.CompanyId[0] == '8') tmp = 128; if (Memory.CompanyId[0] == '9') tmp = 144; if (Memory.CompanyId[0] == 'A') tmp = 160; if (Memory.CompanyId[0] == 'B') tmp = 176; if (Memory.CompanyId[0] == 'C') tmp = 192; if (Memory.CompanyId[0] == 'D') tmp = 208; if (Memory.CompanyId[0] == 'E') tmp = 224; if (Memory.CompanyId[0] == 'F') tmp = 240; if (tmp != -1) { if (Memory.CompanyId[1] == '0') tmp += 0; else if (Memory.CompanyId[1] == '1') tmp += 1; else if (Memory.CompanyId[1] == '2') tmp += 2; else if (Memory.CompanyId[1] == '3') tmp += 3; else if (Memory.CompanyId[1] == '4') tmp += 4; else if (Memory.CompanyId[1] == '5') tmp += 5; else if (Memory.CompanyId[1] == '6') tmp += 6; else if (Memory.CompanyId[1] == '7') tmp += 7; else if (Memory.CompanyId[1] == '8') tmp += 8; else if (Memory.CompanyId[1] == '9') tmp += 9; else if (Memory.CompanyId[1] == 'A') tmp += 10; else if (Memory.CompanyId[1] == 'B') tmp += 11; else if (Memory.CompanyId[1] == 'C') tmp += 12; else if (Memory.CompanyId[1] == 'D') tmp += 13; else if (Memory.CompanyId[1] == 'E') tmp += 14; else if (Memory.CompanyId[1] == 'F') tmp += 15; else tmp = 0; } else tmp = 0; if (tmp == 0) tmp = ((Memory.ROMSpeed & 0x0F) != 0) ? Memory.ROM[0x0FFDA] : Memory.ROM[0x7FDA]; switch (tmp) { case 0: strcpy(text, "INVALID COMPANY"); break; case 1: strcpy(text, "Nintendo"); break; case 2: strcpy(text, "Ajinomoto"); break; case 3: strcpy(text, "Imagineer-Zoom"); break; case 4: strcpy(text, "Chris Gray Enterprises Inc."); break; case 5: strcpy(text, "Zamuse"); break; case 6: strcpy(text, "Falcom"); break; case 7: strcpy(text, NOTKNOWN "7"); break; case 8: strcpy(text, "Capcom"); break; case 9: strcpy(text, "HOT-B"); break; case 10: strcpy(text, "Jaleco"); break; case 11: strcpy(text, "Coconuts"); break; case 12: strcpy(text, "Rage Software"); break; case 13: strcpy(text, "Micronet"); break; case 14: strcpy(text, "Technos"); break; case 15: strcpy(text, "Mebio Software"); break; case 16: strcpy(text, "SHOUEi System"); break; case 17: strcpy(text, "Starfish"); break; case 18: strcpy(text, "Gremlin Graphics"); break; case 19: strcpy(text, "Electronic Arts"); break; case 20: strcpy(text, "NCS / Masaya"); break; case 21: strcpy(text, "COBRA Team"); break; case 22: strcpy(text, "Human/Field"); break; case 23: strcpy(text, "KOEI"); break; case 24: strcpy(text, "Hudson Soft"); break; case 25: strcpy(text, "Game Village"); break; case 26: strcpy(text, "Yanoman"); break; case 27: strcpy(text, NOTKNOWN "27"); break; case 28: strcpy(text, "Tecmo"); break; case 29: strcpy(text, NOTKNOWN "29"); break; case 30: strcpy(text, "Open System"); break; case 31: strcpy(text, "Virgin Games"); break; case 32: strcpy(text, "KSS"); break; case 33: strcpy(text, "Sunsoft"); break; case 34: strcpy(text, "POW"); break; case 35: strcpy(text, "Micro World"); break; case 36: strcpy(text, NOTKNOWN "36"); break; case 37: strcpy(text, NOTKNOWN "37"); break; case 38: strcpy(text, "Enix"); break; case 39: strcpy(text, "Loriciel/Electro Brain"); break; case 40: strcpy(text, "Kemco"); break; case 41: strcpy(text, "Seta Co.,Ltd."); break; case 42: strcpy(text, "Culture Brain"); break; case 43: strcpy(text, "Irem Japan"); break; case 44: strcpy(text, "Pal Soft"); break; case 45: strcpy(text, "Visit Co.,Ltd."); break; case 46: strcpy(text, "INTEC Inc."); break; case 47: strcpy(text, "System Sacom Corp."); break; case 48: strcpy(text, "Viacom New Media"); break; case 49: strcpy(text, "Carrozzeria"); break; case 50: strcpy(text, "Dynamic"); break; case 51: strcpy(text, "Nintendo"); break; case 52: strcpy(text, "Magifact"); break; case 53: strcpy(text, "Hect"); break; case 54: strcpy(text, NOTKNOWN "54"); break; case 55: strcpy(text, NOTKNOWN "55"); break; case 56: strcpy(text, "Capcom Europe"); break; case 57: strcpy(text, "Accolade Europe"); break; case 58: strcpy(text, NOTKNOWN "58"); break; case 59: strcpy(text, "Arcade Zone"); break; case 60: strcpy(text, "Empire Software"); break; case 61: strcpy(text, "Loriciel"); break; case 62: strcpy(text, "Gremlin Graphics"); break; case 63: strcpy(text, NOTKNOWN "63"); break; case 64: strcpy(text, "Seika Corp."); break; case 65: strcpy(text, "UBI Soft"); break; case 66: strcpy(text, NOTKNOWN "66"); break; case 67: strcpy(text, NOTKNOWN "67"); break; case 68: strcpy(text, "LifeFitness Exertainment"); break; case 69: strcpy(text, NOTKNOWN "69"); break; case 70: strcpy(text, "System 3"); break; case 71: strcpy(text, "Spectrum Holobyte"); break; case 72: strcpy(text, NOTKNOWN "72"); break; case 73: strcpy(text, "Irem"); break; case 74: strcpy(text, NOTKNOWN "74"); break; case 75: strcpy(text, "Raya Systems/Sculptured Software"); break; case 76: strcpy(text, "Renovation Products"); break; case 77: strcpy(text, "Malibu Games/Black Pearl"); break; case 78: strcpy(text, NOTKNOWN "78"); break; case 79: strcpy(text, "U.S. Gold"); break; case 80: strcpy(text, "Absolute Entertainment"); break; case 81: strcpy(text, "Acclaim"); break; case 82: strcpy(text, "Activision"); break; case 83: strcpy(text, "American Sammy"); break; case 84: strcpy(text, "GameTek"); break; case 85: strcpy(text, "Hi Tech Expressions"); break; case 86: strcpy(text, "LJN Toys"); break; case 87: strcpy(text, NOTKNOWN "87"); break; case 88: strcpy(text, NOTKNOWN "88"); break; case 89: strcpy(text, NOTKNOWN "89"); break; case 90: strcpy(text, "Mindscape"); break; case 91: strcpy(text, "Romstar, Inc."); break; case 92: strcpy(text, NOTKNOWN "92"); break; case 93: strcpy(text, "Tradewest"); break; case 94: strcpy(text, NOTKNOWN "94"); break; case 95: strcpy(text, "American Softworks Corp."); break; case 96: strcpy(text, "Titus"); break; case 97: strcpy(text, "Virgin Interactive Entertainment"); break; case 98: strcpy(text, "Maxis"); break; case 99: strcpy(text, "Origin/FCI/Pony Canyon"); break; case 100: strcpy(text, NOTKNOWN "100"); break; case 101: strcpy(text, NOTKNOWN "101"); break; case 102: strcpy(text, NOTKNOWN "102"); break; case 103: strcpy(text, "Ocean"); break; case 104: strcpy(text, NOTKNOWN "104"); break; case 105: strcpy(text, "Electronic Arts"); break; case 106: strcpy(text, NOTKNOWN "106"); break; case 107: strcpy(text, "Laser Beam"); break; case 108: strcpy(text, NOTKNOWN "108"); break; case 109: strcpy(text, NOTKNOWN "109"); break; case 110: strcpy(text, "Elite"); break; case 111: strcpy(text, "Electro Brain"); break; case 112: strcpy(text, "Infogrames"); break; case 113: strcpy(text, "Interplay"); break; case 114: strcpy(text, "LucasArts"); break; case 115: strcpy(text, "Parker Brothers"); break; case 116: strcpy(text, "Konami"); break; case 117: strcpy(text, "STORM"); break; case 118: strcpy(text, NOTKNOWN "118"); break; case 119: strcpy(text, NOTKNOWN "119"); break; case 120: strcpy(text, "THQ Software"); break; case 121: strcpy(text, "Accolade Inc."); break; case 122: strcpy(text, "Triffix Entertainment"); break; case 123: strcpy(text, NOTKNOWN "123"); break; case 124: strcpy(text, "Microprose"); break; case 125: strcpy(text, NOTKNOWN "125"); break; case 126: strcpy(text, NOTKNOWN "126"); break; case 127: strcpy(text, "Kemco"); break; case 128: strcpy(text, "Misawa"); break; case 129: strcpy(text, "Teichio"); break; case 130: strcpy(text, "Namco Ltd."); break; case 131: strcpy(text, "Lozc"); break; case 132: strcpy(text, "Koei"); break; case 133: strcpy(text, NOTKNOWN "133"); break; case 134: strcpy(text, "Tokuma Shoten Intermedia"); break; case 135: strcpy(text, "Tsukuda Original"); break; case 136: strcpy(text, "DATAM-Polystar"); break; case 137: strcpy(text, NOTKNOWN "137"); break; case 138: strcpy(text, NOTKNOWN "138"); break; case 139: strcpy(text, "Bullet-Proof Software"); break; case 140: strcpy(text, "Vic Tokai"); break; case 141: strcpy(text, NOTKNOWN "141"); break; case 142: strcpy(text, "Character Soft"); break; case 143: strcpy(text, "I'Max"); break; case 144: strcpy(text, "Takara"); break; case 145: strcpy(text, "CHUN Soft"); break; case 146: strcpy(text, "Video System Co., Ltd."); break; case 147: strcpy(text, "BEC"); break; case 148: strcpy(text, NOTKNOWN "148"); break; case 149: strcpy(text, "Varie"); break; case 150: strcpy(text, "Yonezawa / S'Pal Corp."); break; case 151: strcpy(text, "Kaneco"); break; case 152: strcpy(text, NOTKNOWN "152"); break; case 153: strcpy(text, "Pack in Video"); break; case 154: strcpy(text, "Nichibutsu"); break; case 155: strcpy(text, "TECMO"); break; case 156: strcpy(text, "Imagineer Co."); break; case 157: strcpy(text, NOTKNOWN "157"); break; case 158: strcpy(text, NOTKNOWN "158"); break; case 159: strcpy(text, NOTKNOWN "159"); break; case 160: strcpy(text, "Telenet"); break; case 161: strcpy(text, "Hori"); break; case 162: strcpy(text, NOTKNOWN "162"); break; case 163: strcpy(text, NOTKNOWN "163"); break; case 164: strcpy(text, "Konami"); break; case 165: strcpy(text, "K.Amusement Leasing Co."); break; case 166: strcpy(text, NOTKNOWN "166"); break; case 167: strcpy(text, "Takara"); break; case 168: strcpy(text, NOTKNOWN "168"); break; case 169: strcpy(text, "Technos Jap."); break; case 170: strcpy(text, "JVC"); break; case 171: strcpy(text, NOTKNOWN "171"); break; case 172: strcpy(text, "Toei Animation"); break; case 173: strcpy(text, "Toho"); break; case 174: strcpy(text, NOTKNOWN "174"); break; case 175: strcpy(text, "Namco Ltd."); break; case 176: strcpy(text, "Media Rings Corp."); break; case 177: strcpy(text, "ASCII Co. Activison"); break; case 178: strcpy(text, "Bandai"); break; case 179: strcpy(text, NOTKNOWN "179"); break; case 180: strcpy(text, "Enix America"); break; case 181: strcpy(text, NOTKNOWN "181"); break; case 182: strcpy(text, "Halken"); break; case 183: strcpy(text, NOTKNOWN "183"); break; case 184: strcpy(text, NOTKNOWN "184"); break; case 185: strcpy(text, NOTKNOWN "185"); break; case 186: strcpy(text, "Culture Brain"); break; case 187: strcpy(text, "Sunsoft"); break; case 188: strcpy(text, "Toshiba EMI"); break; case 189: strcpy(text, "Sony Imagesoft"); break; case 190: strcpy(text, NOTKNOWN "190"); break; case 191: strcpy(text, "Sammy"); break; case 192: strcpy(text, "Taito"); break; case 193: strcpy(text, NOTKNOWN "193"); break; case 194: strcpy(text, "Kemco"); break; case 195: strcpy(text, "Square"); break; case 196: strcpy(text, "Tokuma Soft"); break; case 197: strcpy(text, "Data East"); break; case 198: strcpy(text, "Tonkin House"); break; case 199: strcpy(text, NOTKNOWN "199"); break; case 200: strcpy(text, "KOEI"); break; case 201: strcpy(text, NOTKNOWN "201"); break; case 202: strcpy(text, "Konami USA"); break; case 203: strcpy(text, "NTVIC"); break; case 204: strcpy(text, NOTKNOWN "204"); break; case 205: strcpy(text, "Meldac"); break; case 206: strcpy(text, "Pony Canyon"); break; case 207: strcpy(text, "Sotsu Agency/Sunrise"); break; case 208: strcpy(text, "Disco/Taito"); break; case 209: strcpy(text, "Sofel"); break; case 210: strcpy(text, "Quest Corp."); break; case 211: strcpy(text, "Sigma"); break; case 212: strcpy(text, "Ask Kodansha Co., Ltd."); break; case 213: strcpy(text, NOTKNOWN "213"); break; case 214: strcpy(text, "Naxat"); break; case 215: strcpy(text, NOTKNOWN "215"); break; case 216: strcpy(text, "Capcom Co., Ltd."); break; case 217: strcpy(text, "Banpresto"); break; case 218: strcpy(text, "Tomy"); break; case 219: strcpy(text, "Acclaim"); break; case 220: strcpy(text, NOTKNOWN "220"); break; case 221: strcpy(text, "NCS"); break; case 222: strcpy(text, "Human Entertainment"); break; case 223: strcpy(text, "Altron"); break; case 224: strcpy(text, "Jaleco"); break; case 225: strcpy(text, NOTKNOWN "225"); break; case 226: strcpy(text, "Yutaka"); break; case 227: strcpy(text, NOTKNOWN "227"); break; case 228: strcpy(text, "T&ESoft"); break; case 229: strcpy(text, "EPOCH Co.,Ltd."); break; case 230: strcpy(text, NOTKNOWN "230"); break; case 231: strcpy(text, "Athena"); break; case 232: strcpy(text, "Asmik"); break; case 233: strcpy(text, "Natsume"); break; case 234: strcpy(text, "King Records"); break; case 235: strcpy(text, "Atlus"); break; case 236: strcpy(text, "Sony Music Entertainment"); break; case 237: strcpy(text, NOTKNOWN "237"); break; case 238: strcpy(text, "IGS"); break; case 239: strcpy(text, NOTKNOWN "239"); break; case 240: strcpy(text, NOTKNOWN "240"); break; case 241: strcpy(text, "Motown Software"); break; case 242: strcpy(text, "Left Field Entertainment"); break; case 243: strcpy(text, "Beam Software"); break; case 244: strcpy(text, "Tec Magik"); break; case 245: strcpy(text, NOTKNOWN "245"); break; case 246: strcpy(text, NOTKNOWN "246"); break; case 247: strcpy(text, NOTKNOWN "247"); break; case 248: strcpy(text, NOTKNOWN "248"); break; case 249: strcpy(text, "Cybersoft"); break; case 250: strcpy(text, NOTKNOWN "250"); break; case 251: strcpy(text, "Psygnosis"); break; case 252: strcpy(text, NOTKNOWN "252"); break; case 253: strcpy(text, NOTKNOWN "253"); break; case 254: strcpy(text, "Davidson"); break; case 255: strcpy(text, NOTKNOWN "255"); break; default: strcpy(text, NOTKNOWN); } } static void RomInfoGetRegionText(char *text) { switch (Memory.ROMRegion) { case 0: strcpy(text, "Japan"); break; case 1: strcpy(text, "USA/Canada"); break; case 2: strcpy(text, "Oceania, Europe, and Asia"); break; case 3: strcpy(text, "Sweden"); break; case 4: strcpy(text, "Finland"); break; case 5: strcpy(text, "Denmark"); break; case 6: strcpy(text, "France"); break; case 7: strcpy(text, "Holland"); break; case 8: strcpy(text, "Spain"); break; case 9: strcpy(text, "Germany, Austria, and Switzerland"); break; case 10: strcpy(text, "Italy"); break; case 11: strcpy(text, "Hong Kong and China"); break; case 12: strcpy(text, "Indonesia"); break; case 13: strcpy(text, "South Korea"); break; case 14: strcpy(text, "Unknown region 14"); break; default: strcpy(text, "Unknown region 15"); } } static pascal OSStatus RomInfoEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) { #pragma unused (inHandlerRef) 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, nil, sizeof(HICommand), nil, &tHICommand); if (err == noErr && tHICommand.commandID == 'clos') { UpdateMenuCommandStatus(true); result = noErr; } break; case kEventCommandProcess: err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, nil, sizeof(HICommand), nil, &tHICommand); if (err == noErr) { switch (tHICommand.commandID) { case 'Clip': RomInfoCopyToClipboard(); result = noErr; } } } } return result; } static char *StaticRAMBitSize(void) { static char tmp[20]; sprintf(tmp, " (%dKbits)", 8 * (Memory.SRAMMask + 1) / 1024); return tmp; } long GetHIToolboxVersion(void) { CFBundleRef bundle; CFStringRef versStr = nil; static unsigned long version = 0; if (version != 0) return version; bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox")); if (bundle) versStr = (CFStringRef) CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("CFBundleShortVersionString")); if (versStr && (CFGetTypeID(versStr) == CFStringGetTypeID())) { int major = 0, minor = 0, bugfix = 0; char sz[20]; CFStringGetCString(versStr, sz, sizeof(sz), kCFStringEncodingUTF8); sscanf(sz, "%d.%d.%d", &major, &minor, &bugfix); version = (major << 8) + (minor << 4) + bugfix; } return version; } 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; }