Merge pull request #602 from MichaelBuckley/mac-merge

Mac merge
This commit is contained in:
OV2 2019-11-28 16:08:08 +01:00 committed by GitHub
commit fff7941ebf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
125 changed files with 17476 additions and 19697 deletions

BIN
macosx/.DS_Store vendored Normal file

Binary file not shown.

3
macosx/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
Build
.DS_Store
xcuserdata

View File

@ -1,118 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en-US">
<head>
<meta http-equiv="content-type" content="text/html;charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<meta name="description" content="References">
<link href="../sty/style.css" rel="stylesheet">
<title>References</title>
</head>
<body>
<h2>References</h2>
<h3>Preferences Dialog</h3>
<h4>Graphics Tab</h4>
<dl>
<dt>Full Screen Mode</dt>
<dd>Toggles full screen/windowed mode. Press esc key to hide full screen window and pause the game.</dd>
<dt>Switch Monitor Resolution</dt>
<dd>Toggles between scaling full screen graphics to the current screen resolution or changing the screen resolution to fit Snes9x's needs.</dd>
<dt>Show Frame Rate</dt>
<dd>Toggles display of the frame rate on/off.</dd>
<dt>Transparency Effects</dt>
<dd>Toggles transparency effects on/off. Transparency effect is used in almost all games so this option is just for hack.</dd>
<dt>Video Mode</dt>
<dd>Choose the image scaling filter which is applied to the raw SNES image.</dd>
<dt>Multitask</dt>
<dd>When this option is on, the rendering process is separated from the emulation thread (except blocky and smooth modes).</dd>
<dt>Keep Overscanned Height</dt>
<dd>Keeps the screen height always 239/478, for some games that change screen height frequently.</dd>
<dt>Sync to Vertical Blank</dt>
<dd>Synchronizes the render timing to the monitor's vertical refresh rate.</dd>
<dt>Stretch Image in Full Screen Mode</dt>
<dd>Stretches the image to fill the screen in full screen mode.</dd>
<dt>Aspect Ratio</dt>
<dd>The aspect ratio of above option: the left is proportional and the right is full width of the monitor.</dd>
<dt>Use Core Image</dt>
<dd>Applies additional Core Image effect after the image filter is applied.</dd>
<dt>Filter...</dt>
<dd>Choose the Core Image filter.</dd>
<dt>Use 32 Bit Color</dt>
<dd>Uses 16,777,216 colors.</dd>
<dt>Use Screen Curvature</dt>
<dd>Adds a warp effect like a CRT-based television.</dd>
<dt>Warp</dt>
<dd>The degree of curvature.</dd>
</dl>
<h4>Sound Tab</h4>
<dl>
<dt>Synchronize</dt>
<dd>Tries and ensures all available samples are buffered so there are no overruns.</dd>
<dt>16 Bit Playback</dt>
<dd>Enables 16-bit playback instead of 8-bit.</dd>
<dt>Stereo</dt>
<dd>Enables stereo sound instead of mono.</dd>
<dt>Reverse Stereo</dt>
<dd>Swaps the left and right stereo channels.</dd>
<dt>Effect...</dt>
<dd>Opens 'Sound Effect' dialog.</dd>
<dt>Playback Rate</dt>
<dd>The real SNES is 32040 Hz. Any values other than 32040 Hz will cause resampling.</dd>
<dt>Output Interval</dt>
<dd>Make sure this value is smaller than the mix buffer length.</dd>
<dt>Mix Buffer Length</dt>
<dd>Too short length will cause crackling noise.</dd>
<dt>Allow Lag</dt>
<dd>Safer from crackling noise, but time-lag becomes more noticeable.</dd>
<dt>Volume</dt>
<dd>Volume of the whole Snes9x sounds.</dd>
<dt>Input Rate</dt>
<dd>Adjusts the sound rate through resampling. For every Input Rate samples generated by the SNES, Playback Rate samples will be produced.</dd>
</dl>
<h4>File Tab</h4>
<dl>
<dt>Save Data in</dt>
<dd>Choose the folder where Snes9x will look for files.</dd>
<dt>Auto Save SRAM</dt>
<dd>Updates SRAM file when SRAM contents are modified. This may cause frequent disk access.</dd>
</dl>
<h4>Accuracy Tab</h4>
<dl>
<dt>HDMA Timing Hack</dt>
<dd>Changes HDMA timing and will 'fix' some games' glitches, but breaks many other games. The default value is 100.</dd>
<dt>Skip CPU Emulation Until the Next Event Comes</dt>
<dd>Skips internal CPU emulation for speed-ups until the next event comes.</dd>
<dt>Allow Invalid VRAM Access</dt>
<dd>Allows to write to VRAM outside blank periods.</dd>
<dt>Apply Specific Game Hacks</dt>
<dd>Applies special hacks for games that can't be emulated correctly.</dd>
<dt>Frame Skip</dt>
<dd>Adjust this value if your Mac is slow.</dd>
<dt>Speed in Turbo Mode</dt>
<dd>The speed when turbo mode is on. Modify in-game with Fn+T, Fn+Y.</dd>
</dl>
<h4>Others Tab</h4>
<dl>
<dt>Toggle Turbo Button</dt>
<dd>Sets 'Turbo' button as a toggle switch.</dd>
<dt>Show Onscreen Information</dt>
<dd>Shows messages from Snes9x on the game screen. When off, messages are put in the standard console.</dd>
<dt>Open Choose ROM Image Dialog at Startup</dt>
<dd>Choose whether open dialog should be shown when Snes9x is launched.</dd>
<dt>Show Dates and Times in Freeze State Selection Screen</dt>
<dd>Shows time stamps on thumbnails in freeze/defrost screen.</dd>
<dt>Save Window Size and Position</dt>
<dd>Saves the sizes and positions of the game window and dialogs so they come back to the same place.</dd>
<dt>Use IPS / UPS Patch</dt>
<dd>When this option is on, Snes9x automatically loads the .ips or .ups file and patch the ROM image.</dd>
<dt>Boot Up BS Games from BS-X</dt>
<dd>When this option is on, BS-X ROM is loaded first, then you launch BS games from the menu in BS-X.</dd>
<dt>When in Background</dt>
<dd>Choose the behavior of Snes9x when it is in back of other applications.</dd>
<dt>Music Box</dt>
<dd>Choose the behavior of Music Box: 'Sound Emulation Only' to only emulate the music system, and 'Whole Emulation' to also emulate the CPU. Music that depends on the CPU running will not sound right without 'Whole Emulation.'</dd>
</dl>
<div style="text-align:center; margin-top:3em"><p>
&lt;<a href="13.html">Prev</a>&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;<a href="15.html">Next</a>&gt;
</p></div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -51,7 +51,7 @@
/*****************************************************/ /*****************************************************/
#if !TARGET_RT_MAC_CFM #if !TARGET_RT_MAC_CFM
#include <IOKit/hid/IOHIDLib.h> #include <IOKit/hid/IOHIDLib.h>
#endif TARGET_RT_MAC_CFM #endif // TARGET_RT_MAC_CFM
//#include <IOKit/hid/IOHIDUsageTables.h> //#include <IOKit/hid/IOHIDUsageTables.h>
#if 0 // NOTE: These are now in <IOKit/hid/IOHIDUsageTables.h> #if 0 // NOTE: These are now in <IOKit/hid/IOHIDUsageTables.h>
@ -109,7 +109,7 @@ typedef enum IOHIDReportType {
// Notes: This is a MachO function pointer. If you're using CFM you have to call MachOFunctionPointerForCFMFunctionPointer. // Notes: This is a MachO function pointer. If you're using CFM you have to call MachOFunctionPointerForCFMFunctionPointer.
typedef void( *IOHIDCallbackFunction ) ( void* target, unsigned long result, void* refcon, void* sender ); typedef void( *IOHIDCallbackFunction ) ( void* target, unsigned long result, void* refcon, void* sender );
typedef void* IOHIDEventStruct; typedef void* IOHIDEventStruct;
#endif TARGET_RT_MAC_CFM #endif // TARGET_RT_MAC_CFM
// Device and Element Interfaces // Device and Element Interfaces

View File

@ -160,7 +160,7 @@
</dict> </dict>
</array> </array>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>Snes9x</string> <string>Snes9x (i386)</string>
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>Snes9x 1.60, Copyright 1996-2019 Snes9x developers.</string> <string>Snes9x 1.60, Copyright 1996-2019 Snes9x developers.</string>
<key>CFBundleHelpBookFolder</key> <key>CFBundleHelpBookFolder</key>
@ -170,7 +170,7 @@
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>APPL.icns</string> <string>APPL.icns</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>com.snes9x.macos.snes9x</string> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>

View File

@ -1,189 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>jma</string>
</array>
<key>CFBundleTypeName</key>
<string>JMA archive</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>JMAf</string>
</array>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSTypeIsPackage</key>
<false/>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>sfc</string>
<string>smc</string>
<string>swc</string>
<string>fig</string>
<string>gd3</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>CART.icns</string>
<key>CFBundleTypeName</key>
<string>Snes9x ROM Image</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>CART</string>
</array>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSTypeIsPackage</key>
<false/>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>srm</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>SRAM.icns</string>
<key>CFBundleTypeName</key>
<string>Snes9x SRAM Data</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>SRAM</string>
</array>
<key>CFBundleTypeRole</key>
<string>None</string>
<key>LSTypeIsPackage</key>
<false/>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>frz</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>SAVE.icns</string>
<key>CFBundleTypeName</key>
<string>Snes9x Freeze Data</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>SAVE</string>
</array>
<key>CFBundleTypeRole</key>
<string>None</string>
<key>LSTypeIsPackage</key>
<false/>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>smv</string>
</array>
<key>CFBundleTypeName</key>
<string>Snes9x Movie Data</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>SMOV</string>
</array>
<key>CFBundleTypeRole</key>
<string>None</string>
<key>LSTypeIsPackage</key>
<false/>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>spc</string>
</array>
<key>CFBundleTypeName</key>
<string>Snes9x SPC Data</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>SSPC</string>
</array>
<key>CFBundleTypeRole</key>
<string>None</string>
<key>LSTypeIsPackage</key>
<false/>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>cht</string>
</array>
<key>CFBundleTypeName</key>
<string>Snes9x Cheat Data</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>SCHT</string>
</array>
<key>CFBundleTypeRole</key>
<string>None</string>
<key>LSTypeIsPackage</key>
<false/>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>rtc</string>
</array>
<key>CFBundleTypeName</key>
<string>Snes9x RTC Data</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>SRTC</string>
</array>
<key>CFBundleTypeRole</key>
<string>None</string>
<key>LSTypeIsPackage</key>
<false/>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>*</string>
</array>
<key>CFBundleTypeOSTypes</key>
<array>
<string>****</string>
</array>
<key>CFBundleTypeRole</key>
<string>None</string>
<key>LSTypeIsPackage</key>
<false/>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>Snes9x (i386)</string>
<key>CFBundleGetInfoString</key>
<string>Snes9x 1.60, Copyright 1996-2019 Snes9x developers.</string>
<key>CFBundleHelpBookFolder</key>
<string>Snes9x Help</string>
<key>CFBundleHelpBookName</key>
<string>Snes9x Help</string>
<key>CFBundleIconFile</key>
<string>APPL.icns</string>
<key>CFBundleIdentifier</key>
<string>com.snes9x.macos.snes9x</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Snes9x</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.60</string>
<key>CFBundleSignature</key>
<string>~9X~</string>
<key>CFBundleVersion</key>
<string>1.60</string>
<key>CSResourcesFileMapped</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,28 @@
/*
* EndianStuff.h
* stackimport
*
* Created by Mr. Z. on 10/06/06.
* Copyright 2006 Mr Z. All rights reserved.
*
*/
#pragma once
#include <stdint.h>
#if RECLASSIFICATION_BUILD_BIG_ENDIAN
#define BIG_ENDIAN_16(value) (value)
#define BIG_ENDIAN_32(value) (value)
#else
#define BIG_ENDIAN_16(value) \
(((((uint16_t)(value))<<8) & 0xFF00) | \
((((uint16_t)(value))>>8) & 0x00FF))
#define BIG_ENDIAN_32(value) \
(((((uint32_t)(value))<<24) & 0xFF000000) | \
((((uint32_t)(value))<< 8) & 0x00FF0000) | \
((((uint32_t)(value))>> 8) & 0x0000FF00) | \
((((uint32_t)(value))>>24) & 0x000000FF))
#endif

View File

@ -0,0 +1,269 @@
/* ===========================================================================
PROJECT: FakeHandles
FILE: FakeHandles.c
PURPOSE: Simulate Handles on machines which only have ANSI-C to easily
port some of the more simple Macintosh code fragments to other
platforms.
(C) Copyright 1998 by Uli Kusterer, all rights reserved.
======================================================================== */
#pragma mark [Headers]
// -----------------------------------------------------------------------------
// Headers:
// -----------------------------------------------------------------------------
#include "FakeHandles.h"
// -----------------------------------------------------------------------------
// Globals:
// -----------------------------------------------------------------------------
/* The last entry in the master pointer array is mis-used to hold a pointer
to another master pointer array. Thus, we have a linked list of master
pointer arrays in RAM, and we don't run out of master pointers as easily. */
MasterPointer gMasterPointers[MASTERPOINTER_CHUNK_SIZE];
long gFakeHandleError = noErr;
/* -----------------------------------------------------------------------------
FakeInitHandles:
Call this to initialize the fake memory Manager at the start of your
program. Only call this once or you'll lose all your Handles and will have
stale memory lying around. Pass the global gMasterPointers in
masterPtrArray.
REVISIONS:
98-08-30 UK Created.
----------------------------------------------------------------------------- */
void FakeInitHandles( MasterPointer* masterPtrArray )
{
long x;
for( x = 0; x < MASTERPOINTER_CHUNK_SIZE; x++ )
{
masterPtrArray[x].actualPointer = NULL;
masterPtrArray[x].used = false;
masterPtrArray[x].memoryFlags = 0;
masterPtrArray[x].size = 0;
}
gFakeHandleError = noErr;
}
/* -----------------------------------------------------------------------------
FakeMoreMasters:
Call this if you need more master pointers Called internally by
FakeNewHandle() when it runs out of master pointers.
REVISIONS:
98-08-30 UK Created.
----------------------------------------------------------------------------- */
void FakeMoreMasters()
{
long x;
MasterPointer* vMPtrBlock;
MasterPointer* vCurrBlock;
// Make a new master pointer block:
vMPtrBlock = malloc( MASTERPOINTER_CHUNK_SIZE *sizeof(MasterPointer) );
if( vMPtrBlock == NULL )
{
gFakeHandleError = memFulErr;
return;
}
// Clear it:
for( x = 0; x < MASTERPOINTER_CHUNK_SIZE; x++ )
{
vMPtrBlock[x].actualPointer = NULL;
vMPtrBlock[x].used = false;
vMPtrBlock[x].memoryFlags = 0;
vMPtrBlock[x].size = 0;
}
// Find last master pointer in last master pointer block:
vCurrBlock = gMasterPointers;
while( vCurrBlock[MASTERPOINTER_CHUNK_SIZE -1].used == true )
vCurrBlock = (MasterPointer*) vCurrBlock[MASTERPOINTER_CHUNK_SIZE-1].actualPointer;
// Make this last master pointer point to our new block:
vCurrBlock[MASTERPOINTER_CHUNK_SIZE-1].actualPointer = (char*) vMPtrBlock;
vCurrBlock[MASTERPOINTER_CHUNK_SIZE-1].used = true;
vMPtrBlock[MASTERPOINTER_CHUNK_SIZE-1].size = MASTERPOINTER_CHUNK_SIZE *sizeof(MasterPointer);
gFakeHandleError = noErr;
}
Handle FakeNewEmptyHandle()
{
Handle theHandle = NULL;
long x;
MasterPointer* vCurrBlock = gMasterPointers;
bool notFound = true;
gFakeHandleError = noErr;
while( notFound )
{
for( x = 0; x < (MASTERPOINTER_CHUNK_SIZE-1); x++ )
{
if( !(vCurrBlock[x].used) )
{
vCurrBlock[x].used = true;
vCurrBlock[x].memoryFlags = 0;
vCurrBlock[x].size = 0;
theHandle = (Handle) &(vCurrBlock[x]);
notFound = false;
break;
}
}
if( !vCurrBlock[MASTERPOINTER_CHUNK_SIZE-1].used ) // Last is unused? We need a new master pointer block!
{
FakeMoreMasters();
if( !vCurrBlock[MASTERPOINTER_CHUNK_SIZE-1].used ) // No new block added?!
notFound = false; // Terminate, it's very likely an error occurred.
}
vCurrBlock = (MasterPointer*) vCurrBlock[MASTERPOINTER_CHUNK_SIZE-1].actualPointer; // Go next master pointer block.
}
return theHandle;
}
/* -----------------------------------------------------------------------------
NewHandle:
Create a new Handle. This creates a new entry in the Master Ptr array and
allocates memory of the specified size for it. Then it returns a Ptr to
this entry.
Returns NULL if not successful. If MemError() is noErr upon a NULL return
value, we are out of master pointers.
REVISIONS:
2001-02-16 UK Added support for error codes.
1998-08-30 UK Created.
----------------------------------------------------------------------------- */
Handle FakeNewHandle( long theSize )
{
MasterPointer * theHandle = (MasterPointer*) FakeNewEmptyHandle();
theHandle->actualPointer = malloc( theSize );
if( theHandle->actualPointer == NULL )
{
FakeDisposeHandle( (Handle) theHandle );
gFakeHandleError = memFulErr;
}
else
theHandle->size = theSize;
return (Handle)theHandle;
}
/* -----------------------------------------------------------------------------
DisposeHandle:
Dispose an existing Handle. Only call this once or you might kill valid
memory or worse.
This frees the memory we use and marks the entry for the specified Handle
as unused.
REVISIONS:
1998-08-30 UK Created.
----------------------------------------------------------------------------- */
void FakeDisposeHandle( Handle theHand )
{
MasterPointer* theEntry = (MasterPointer*) theHand;
if( theEntry->actualPointer )
free( theEntry->actualPointer );
theEntry->used = false;
theEntry->actualPointer = NULL;
theEntry->memoryFlags = 0;
theEntry->size = 0;
}
void FakeEmptyHandle( Handle theHand )
{
MasterPointer* theEntry = (MasterPointer*) theHand;
if( theEntry->actualPointer )
free( theEntry->actualPointer );
theEntry->actualPointer = NULL;
}
/* -----------------------------------------------------------------------------
GetHandleSize:
Return the size of an existing Handle. This simply examines the "size"
field of the Handle's entry.
REVISIONS:
1998-08-30 UK Created.
----------------------------------------------------------------------------- */
long FakeGetHandleSize( Handle theHand )
{
MasterPointer* theEntry = (MasterPointer*) theHand;
gFakeHandleError = noErr;
return( theEntry->size );
}
/* -----------------------------------------------------------------------------
SetHandleSize:
Change the size of an existing Handle. This reallocates the Handle (keeping
its data) and updates the size field of the Handle's entry accordingly.
REVISIONS:
1998-08-30 UK Created.
----------------------------------------------------------------------------- */
void FakeSetHandleSize( Handle theHand, long theSize )
{
MasterPointer* theEntry = (MasterPointer*) theHand;
char* thePtr;
thePtr = theEntry->actualPointer;
thePtr = realloc( thePtr, theSize );
if( thePtr )
{
theEntry->actualPointer = thePtr;
theEntry->size = theSize;
gFakeHandleError = noErr;
}
else
gFakeHandleError = memFulErr;
}

View File

@ -0,0 +1,114 @@
/* ===========================================================================
PROJECT: FakeHandles
FILE: FakeHandles.h
PURPOSE: Simulate Handles on machines which only have ANSI-C to easily
port some of the more simple Macintosh code fragments to other
platforms.
(C) Copyright 1998 by Uli Kusterer, all rights reserved.
DIRECTIONS:
A Handle is a memory block that remembers its size automatically.
To the user, a Handle is simply a pointer to a pointer to the actual
data. Dereference it twice to get at the actual data. Before you
pass a once-dereferenced Handle to any other functions, you need to
call HLock() on it to avoid that it moves. Call HUnlock() when you
are finished with that.
To create a Handle, use NewHandle(). To free a Handle, call
DisposeHandle(). To resize use SetHandleSize() (the Handle itself
will not change, but the pointer to the actual data may change),
GetHandleSize() returns the actual size of the Handle.
Before making any of these calls, you *must have* called
InitHandles().
======================================================================== */
#ifndef FAKEHANDLES_H
#define FAKEHANDLES_H
#pragma mark [Headers]
// -----------------------------------------------------------------------------
// Headers:
// -----------------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
// -----------------------------------------------------------------------------
// Constants:
// -----------------------------------------------------------------------------
#ifndef NULL
#define NULL 0L
#endif
#define MASTERPOINTER_CHUNK_SIZE 1024 // Size of blocks of master pointers we allocate in one go.
// Error codes MemError() may return after Handle calls:
enum
{
#ifndef __MACTYPES__
noErr = 0, // No error, success.
#endif /* __MACTYPES__ */
memFulErr = -108 // Out of memory error.
};
// -----------------------------------------------------------------------------
// Data Types:
// -----------------------------------------------------------------------------
// Data types special to Mac:
typedef char** Handle;
#ifndef __MACTYPES__
typedef unsigned char Boolean;
#endif /* __MACTYPES__ */
// Private data structure used internally to keep track of Handles:
typedef struct MasterPointer
{
char* actualPointer; // The actual Pointer we're pointing to.
Boolean used; // Is this master Ptr being used?
long memoryFlags; // Some flags for this Handle.
long size; // The size of this Handle.
} MasterPointer;
// -----------------------------------------------------------------------------
// Globals:
// -----------------------------------------------------------------------------
extern MasterPointer gMasterPointers[MASTERPOINTER_CHUNK_SIZE];
extern long gFakeHandleError;
// -----------------------------------------------------------------------------
// Prototypes:
// -----------------------------------------------------------------------------
extern void FakeInitHandles( MasterPointer* masterPtrArray );
extern Handle FakeNewHandle( long theSize );
extern void FakeDisposeHandle( Handle theHand );
extern long FakeGetHandleSize( Handle theHand );
extern void FakeSetHandleSize( Handle theHand, long theSize );
extern void FakeMoreMasters( void );
extern Handle FakeNewEmptyHandle();
extern void FakeEmptyHandle( Handle theHand );
#endif /*FAKEHANDLES_H*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,84 @@
//
// FakeResources.h
// ReClassicfication
//
// Created by Uli Kusterer on 21.02.13.
// Copyright (c) 2013 Uli Kusterer. All rights reserved.
//
#ifndef ReClassicfication_FakeResources_h
#define ReClassicfication_FakeResources_h
#include "FakeHandles.h"
// Possible return values of FakeResError():
#ifndef __MACERRORS__
enum
{
resNotFound = -192,
resFNotFound = -193,
addResFailed = -194,
rmvResFailed = -196,
resAttrErr = -198,
eofErr = -39,
fnfErr = -43
};
#endif /* __MACERRORS__ */
#ifndef __RESOURCES__
// Resource attribute bit flags:
enum
{
resReserved = (1 << 0), // Apparently not yet used.
resChanged = (1 << 1),
resPreload = (1 << 2),
resProtected = (1 << 3),
resLocked = (1 << 4),
resPurgeable = (1 << 5),
resSysHeap = (1 << 6),
resReserved2 = (1 << 7) // Apparently not yet used.
};
#endif
typedef unsigned char FakeStr255[256];
int16_t FakeOpenResFile( const unsigned char* inPath );
void FakeCloseResFile( int16_t resRefNum );
Handle FakeGet1Resource( uint32_t resType, int16_t resID );
Handle FakeGetResource( uint32_t resType, int16_t resID );
int16_t FakeCurResFile();
void FakeUseResFile( int16_t resRefNum );
void FakeUpdateResFile( int16_t inFileRefNum );
int16_t FakeHomeResFile( Handle theResource );
int16_t FakeCount1Types();
int16_t FakeCount1Resources( uint32_t resType );
int16_t FakeCountTypes();
int16_t FakeCountResources( uint32_t resType );
void FakeGet1IndType( uint32_t * resType, int16_t index );
Handle FakeGet1IndResource( uint32_t resType, int16_t index );
void FakeGetResInfo( Handle theResource, int16_t * theID, uint32_t * theType, FakeStr255 * name );
void FakeSetResInfo( Handle theResource, int16_t theID, FakeStr255 name );
void FakeAddResource( Handle theData, uint32_t theType, int16_t theID, FakeStr255 name );
void FakeChangedResource( Handle theResource );
void FakeRemoveResource( Handle theResource );
void FakeWriteResource( Handle theResource );
void FakeLoadResource( Handle theResource );
void FakeReleaseResource( Handle theResource );
void FakeSetResLoad(bool load);
int16_t FakeResError();
// Private calls for internal use/tests:
void FakeRedirectResFileToPath( int16_t inFileRefNum, const char* cPath );
struct FakeResourceMap* FakeResFileOpen( const char* inPath, const char* inMode );
struct FakeResourceMap* FakeFindResourceMap( int16_t inFileRefNum, struct FakeResourceMap*** outPrevMapPtr );
int16_t FakeCount1ResourcesInMap( uint32_t resType, struct FakeResourceMap* inMap );
int16_t FakeCount1TypesInMap( struct FakeResourceMap* inMap );
#endif

View File

@ -0,0 +1,47 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#import <Cocoa/Cocoa.h>
#import <snes9x_framework/snes9x_framework.h>
@interface AppDelegate : NSObject <NSApplicationDelegate, S9xInputDelegate>
@property (nonatomic, readonly, assign) BOOL isRunningEmulation;
- (void)setButtonCode:(S9xButtonCode)buttonCode forKeyCode:(int16)keyCode player:(int8)player;
- (void)clearButton:(S9xButtonCode)button forPlayer:(int8)player;
- (NSArray<S9xJoypad *> *)listJoypads;
- (void)setPlayer:(int8)player forVendorID:(uint32)vendorID productID:(uint32)productID index:(uint32)index;
- (BOOL)setButton:(S9xButtonCode)button forVendorID:(uint32)vendorID productID:(uint32)productID index:(uint32)index cookie:(uint32)cookie value:(int32)value;
- (void)clearJoypadForVendorID:(uint32)vendorID productID:(uint32)productID index:(uint32)index buttonCode:(S9xButtonCode)buttonCode;
- (NSString *)labelForVendorID:(uint32)vendorID productID:(uint32)productID cookie:(uint32)cookie value:(int32)value;
- (NSString *)prefsKeyForVendorID:(uint32)vendorID productID:(uint32)productID index:(uint32)index;
- (BOOL)getValuesFromString:(NSString *)str vendorID:(uint32 *)vendorID productID:(uint32 *)productID index:(uint32 *)index;
- (NSString *)prefValueForCookie:(uint32)cookie value:(int32)value;
- (BOOL)getValuesFromString:(NSString *)str cookie:(uint32 *)cookie value:(int32 *)value;
- (void)setVideoMode:(int)videoMode;
- (void)setShowFPS:(BOOL)showFPS;
@end

516
macosx/Snes9x/AppDelegate.m Normal file
View File

@ -0,0 +1,516 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#import <Carbon/Carbon.h>
#import "AppDelegate.h"
#import "S9xPrefsConstants.h"
#import "S9xPrefsViewController.h"
@interface AppDelegate ()
@property (nonatomic, strong) S9xEngine *s9xEngine;
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSNumber *> *keys;
@property (nonatomic, strong) NSWindow *window;
@property (nonatomic, strong, nullable) NSWindowController *prefsWindowController;
@end
static NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow";
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
self.s9xEngine = [S9xEngine new];
self.s9xEngine.inputDelegate = self;
[self setupDefaults];
[self importRecentItems];
NSWindow *window = [[NSWindow alloc] initWithContentRect:s9xView.frame styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable backing:NSBackingStoreBuffered defer:NO];
window.contentView.wantsLayer = YES;
window.contentView.layer.backgroundColor = NSColor.blackColor.CGColor;
window.title = @"Snes9x";
window.restorationClass = [self class];
window.frameAutosaveName = kMainWindowIdentifier;
window.releasedWhenClosed = NO;
[window.contentView addSubview:s9xView];
[s9xView.topAnchor constraintEqualToAnchor:window.contentView.topAnchor].active = YES;
[s9xView.bottomAnchor constraintEqualToAnchor:window.contentView.bottomAnchor].active = YES;
[s9xView.centerXAnchor constraintEqualToAnchor:window.contentView.centerXAnchor].active = YES;
[s9xView.leftAnchor constraintGreaterThanOrEqualToAnchor:window.contentView.leftAnchor].active = YES;
[s9xView.rightAnchor constraintLessThanOrEqualToAnchor:window.contentView.rightAnchor].active = YES;
if ( ![window setFrameUsingName:kMainWindowIdentifier] )
{
[window center];
}
self.window = window;
[NSNotificationCenter.defaultCenter addObserverForName:NSWindowWillCloseNotification object:window queue:NSOperationQueue.mainQueue usingBlock:^(NSNotification *notification)
{
[self.s9xEngine pause];
}];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
- (void)setupDefaults
{
NSUserDefaults *defaults = NSUserDefaults.standardUserDefaults;
NSDictionary *defaultSettings = @{
kKeyboardPrefs : @{
@(kUp).stringValue : @(kVK_UpArrow),
@(kDown).stringValue : @(kVK_DownArrow),
@(kLeft).stringValue : @(kVK_LeftArrow),
@(kRight).stringValue : @(kVK_RightArrow),
@(kY).stringValue : @(kVK_ANSI_X),
@(kB).stringValue : @(kVK_ANSI_C),
@(kX).stringValue : @(kVK_ANSI_D),
@(kA).stringValue : @(kVK_ANSI_V),
@(kL).stringValue : @(kVK_ANSI_A),
@(kR).stringValue : @(kVK_ANSI_S),
@(kStart).stringValue : @(kVK_Space),
@(kSelect).stringValue : @(kVK_Return),
@(kNumButtons + kUp).stringValue : @(kVK_ANSI_Keypad8),
@(kNumButtons + kDown).stringValue : @(kVK_ANSI_Keypad2),
@(kNumButtons + kLeft).stringValue : @(kVK_ANSI_Keypad4),
@(kNumButtons + kRight).stringValue : @(kVK_ANSI_Keypad6),
@(kNumButtons + kY).stringValue : @(kVK_PageDown),
@(kNumButtons + kB).stringValue : @(kVK_PageUp),
@(kNumButtons + kX).stringValue : @(kVK_End),
@(kNumButtons + kA).stringValue : @(kVK_Home),
@(kNumButtons + kL).stringValue : @(kVK_ANSI_Keypad0),
@(kNumButtons + kR).stringValue : @(kVK_ANSI_KeypadDecimal),
@(kNumButtons + kStart).stringValue : @(kVK_ANSI_KeypadEnter),
@(kNumButtons + kSelect).stringValue : @(kVK_ANSI_KeypadPlus),
@(kKeyFastForward).stringValue : @(kVK_ANSI_Backslash),
@(kKeyFreeze).stringValue : @(kVK_ANSI_1),
@(kKeyDefrost).stringValue : @(kVK_ANSI_0),
@(kKeyScreenshot).stringValue : @(kVK_ANSI_Grave),
@(kKeySPC).stringValue : @(kVK_ANSI_R),
@(kKeyScopeTurbo).stringValue : @(kVK_ANSI_B),
@(kKeyScopePause).stringValue : @(kVK_ANSI_N),
@(kKeyScopeCursor).stringValue : @(kVK_ANSI_M),
@(kKeyOffScreen).stringValue : @(kVK_Tab),
@(kKeyFunction).stringValue : @(kVK_ANSI_Slash),
@(kKeyAlt).stringValue : @(kVK_ANSI_Period),
@(kKeyFFDown).stringValue : @(kVK_ANSI_Q),
@(kKeyFFUp).stringValue : @(kVK_ANSI_W),
@(kKeyEsc).stringValue : @(kVK_Escape),
@(kKeyTC).stringValue : @(kVK_ANSI_Comma)
},
kShowFPSPref: @(NO),
kVideoModePref:@(VIDEOMODE_BLOCKY)
};
[defaults registerDefaults:defaultSettings];
self.keys = [[defaults objectForKey:kKeyboardPrefs] mutableCopy];
for (NSString *control in [self.keys copy])
{
NSInteger key = control.integerValue;
NSInteger player = key / kNumButtons;
S9xButtonCode buttonCode = (S9xButtonCode)(key - (kNumButtons * player));
[self setButtonCode:buttonCode forKeyCode:self.keys[control].integerValue player:player];
}
for ( S9xJoypad *joypad in [self listJoypads])
{
NSMutableDictionary *joypadPrefs = [[defaults objectForKey:kJoypadInputPrefs] mutableCopy];
if (joypadPrefs == nil)
{
joypadPrefs = [NSMutableDictionary new];
[defaults synchronize];
}
NSString *key = [self prefsKeyForVendorID:joypad.vendorID productID:joypad.productID index:joypad.index];
NSMutableDictionary *devicePrefs = [joypadPrefs[key] mutableCopy];
if (devicePrefs == nil)
{
devicePrefs = [NSMutableDictionary new];
for (S9xJoypadInput *input in [self.s9xEngine getInputsForVendorID:joypad.vendorID productID:joypad.productID index:joypad.index])
{
devicePrefs[@(input.buttonCode).stringValue] = [self prefValueForCookie:input.cookie value:input.value];
}
joypadPrefs[key] = devicePrefs;
[defaults setObject:joypadPrefs forKey:kJoypadInputPrefs];
[defaults synchronize];
}
else
{
[self.s9xEngine clearJoypadForVendorID:joypad.vendorID productID:joypad.productID index:joypad.index];
for (NSString *buttonCodeString in devicePrefs)
{
S9xButtonCode buttonCode = (S9xButtonCode)buttonCodeString.intValue;
NSString *str = devicePrefs[buttonCodeString];
uint32 cookie = 0;
int32 value = -1;
if ([self getValuesFromString:str cookie:&cookie value:&value])
{
[self setButton:buttonCode forVendorID:joypad.vendorID productID:joypad.productID index:joypad.index cookie:cookie value:value];
}
}
}
}
[self importKeySettings];
[self importGraphicsSettings];
[defaults synchronize];
}
- (void)setButtonCode:(S9xButtonCode)buttonCode forKeyCode:(int16)keyCode player:(int8)player
{
if (keyCode < 0)
{
return;
}
self.keys[@(buttonCode + (kNumButtons * player)).stringValue] = @(keyCode);
S9xButtonCode oldButton = kNumButtons;
int8 oldPlayer = -1;
if ([self.s9xEngine setButton:buttonCode forKey:keyCode player:player oldButton:&oldButton oldPlayer:&oldPlayer oldKey:NULL])
{
if (oldButton >= 0 && oldButton < kNumButtons && oldPlayer >= 0 && oldPlayer < MAC_MAX_PLAYERS && (oldPlayer != player || oldButton != buttonCode))
{
[self.keys removeObjectForKey:@(oldButton + (kNumButtons * oldPlayer)).stringValue];
}
[NSUserDefaults.standardUserDefaults setObject:[self.keys copy] forKey:kKeyboardPrefs];
}
}
- (void)clearButton:(S9xButtonCode)button forPlayer:(int8)player
{
[self.s9xEngine clearButton:button forPlayer:player];
NSMutableDictionary *keyDict = [[NSUserDefaults.standardUserDefaults objectForKey:kKeyboardPrefs] mutableCopy];
[keyDict removeObjectForKey:@(button).stringValue];
[NSUserDefaults.standardUserDefaults setObject:[keyDict copy] forKey:kKeyboardPrefs];
[NSUserDefaults.standardUserDefaults synchronize];
}
- (NSArray<S9xJoypad *> *)listJoypads
{
return [self.s9xEngine listJoypads];
}
- (NSString *)prefsKeyForVendorID:(uint32)vendorID productID:(uint32)productID index:(uint32)index
{
return [NSString stringWithFormat:@"%@:%@:%@", @(vendorID).stringValue, @(productID).stringValue, @(index).stringValue];
}
- (BOOL)getValuesFromString:(NSString *)str vendorID:(uint32 *)vendorID productID:(uint32 *)productID index:(uint32 *)index
{
if (vendorID == NULL || productID == NULL || index == NULL)
{
return NO;
}
NSArray<NSString *> *components = [str componentsSeparatedByString:@":"];
if (components.count != 3)
{
return NO;
}
*vendorID = components[0].intValue;
*productID = components[1].intValue;
*index = components[2].intValue;
return YES;
}
- (NSString *)prefValueForCookie:(uint32)cookie value:(int32)value
{
return [NSString stringWithFormat:@"%@:%@", @(cookie).stringValue, @(value).stringValue];
}
- (BOOL)getValuesFromString:(NSString *)str cookie:(uint32 *)cookie value:(int32 *)value
{
if (cookie == NULL || value == NULL)
{
return NO;
}
NSArray<NSString *> *components = [str componentsSeparatedByString:@":"];
if (components.count != 2)
{
return NO;
}
*cookie = components.firstObject.intValue;
*value = components.lastObject.intValue;
return YES;
}
- (void)setPlayer:(int8)player forVendorID:(uint32)vendorID productID:(uint32)productID index:(uint32)index
{
int8 oldPlayer = -1;
[self.s9xEngine setPlayer:player forVendorID:vendorID productID:productID index:index oldPlayer:&oldPlayer];
NSMutableDictionary *playersDict = [[NSUserDefaults.standardUserDefaults objectForKey:kJoypadPlayerPrefs] mutableCopy];
if (playersDict == nil)
{
playersDict = [NSMutableDictionary new];
}
if (oldPlayer >= 0 && player != oldPlayer)
{
[playersDict removeObjectForKey:@(oldPlayer).stringValue];
}
playersDict[@(player).stringValue] = [self prefsKeyForVendorID:vendorID productID:productID index:index];
[NSUserDefaults.standardUserDefaults setObject:[playersDict copy] forKey:kJoypadPlayerPrefs];
}
- (BOOL)setButton:(S9xButtonCode)button forVendorID:(uint32)vendorID productID:(uint32)productID index:(uint32)index cookie:(uint32)cookie value:(int32)value
{
S9xButtonCode oldButton = (S9xButtonCode)-1;
BOOL result = [self.s9xEngine setButton:button forVendorID:vendorID productID:productID index:index cookie:cookie value:value oldButton:&oldButton];
NSMutableDictionary *prefsDict = [[NSUserDefaults.standardUserDefaults objectForKey:kJoypadInputPrefs] mutableCopy];
NSString *key = [self prefsKeyForVendorID:vendorID productID:productID index:index];
NSMutableDictionary *joypadDict = [prefsDict[key] mutableCopy];
if (result && button != oldButton)
{
[joypadDict removeObjectForKey:@(oldButton).stringValue];
}
joypadDict[@(button).stringValue] = [self prefValueForCookie:cookie value:value];
prefsDict[key] = [joypadDict copy];
[NSUserDefaults.standardUserDefaults setObject:[prefsDict copy] forKey:kJoypadInputPrefs];
return result;
}
- (void)clearJoypadForVendorID:(uint32)vendorID productID:(uint32)productID index:(uint32)index buttonCode:(S9xButtonCode)buttonCode
{
[self.s9xEngine clearJoypadForVendorID:vendorID productID:productID index:index buttonCode:buttonCode];
NSString *key = [self prefsKeyForVendorID:vendorID productID:productID index:index];
NSMutableDictionary *joypadsDict = [[NSUserDefaults.standardUserDefaults objectForKey:kJoypadInputPrefs] mutableCopy];
NSMutableDictionary *deviceDict = [joypadsDict[key] mutableCopy];
[deviceDict removeObjectForKey:@(buttonCode).stringValue];
joypadsDict[key] = deviceDict;
[NSUserDefaults.standardUserDefaults setObject:[joypadsDict copy] forKey:kJoypadInputPrefs];
[NSUserDefaults.standardUserDefaults synchronize];
}
- (NSString *)labelForVendorID:(uint32)vendorID productID:(uint32)productID cookie:(uint32)cookie value:(int32)value
{
return [self.s9xEngine labelForVendorID:vendorID productID:productID cookie:cookie value:value];
}
- (void)importRecentItems
{
const NSInteger maxRecents = 20;
for (NSInteger i = maxRecents - 1; i >= 0; --i)
{
NSString *key = [NSString stringWithFormat:@"RecentItem_%02tu", i];
NSString *recentItem = [NSUserDefaults.standardUserDefaults objectForKey:key];
if (recentItem != nil)
{
[NSDocumentController.sharedDocumentController noteNewRecentDocumentURL:[NSURL fileURLWithPath:recentItem]];
[NSUserDefaults.standardUserDefaults removeObjectForKey:key];
}
}
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)importKeySettings
{
NSData *data = [self objectForPrefOSCode:'keyb'];
NSUInteger length = data.length;
char *bytes = (char*)data.bytes;
for ( NSUInteger i = 0; i < length; ++i )
{
// The enum values for controls changed between the Carbon and Cocoa versions.
// The first 24 enum values are the same, but we have to adjust after that.
if ( i < 24 )
{
[self setButtonCode:(S9xButtonCode)(i - (i / 12)) forKeyCode:bytes[i] player:i / 12];
}
else
{
[self setButtonCode:(S9xButtonCode)(i - 24 + kKeyFastForward) forKeyCode:bytes[i] player:0];
}
}
}
- (void)importGraphicsSettings
{
NSData *data = [self objectForPrefOSCode:'dfps'];
if (data != nil)
{
[NSUserDefaults.standardUserDefaults setBool:(data.length > 0 && ((char *)data.bytes)[0]) forKey:kShowFPSPref];
}
[self setShowFPS:[NSUserDefaults.standardUserDefaults boolForKey:kShowFPSPref]];
data = [self objectForPrefOSCode:'Vmod'];
if ( data != nil)
{
[NSUserDefaults.standardUserDefaults setInteger:((data.length >= 0 && ((char *)data.bytes)[0]) ? VIDEOMODE_SMOOTH : VIDEOMODE_BLOCKY) forKey:kVideoModePref];
}
[self setVideoMode:(int)[NSUserDefaults.standardUserDefaults integerForKey:kVideoModePref]];
}
- (id)objectForPrefOSCode:(uint32_t)osCode
{
NSString *key = [@"Preferences_" stringByAppendingString:[[NSString alloc] initWithBytes:(char *)&osCode length:sizeof(uint32_t) encoding:NSASCIIStringEncoding]];
id obj = [NSUserDefaults.standardUserDefaults objectForKey:key];
if (obj == nil)
{
osCode =CFSwapInt32(osCode);
key = [@"Preferences_" stringByAppendingString:[[NSString alloc] initWithBytes:(char *)&osCode length:sizeof(uint32_t) encoding:NSASCIIStringEncoding]];
obj = [NSUserDefaults.standardUserDefaults objectForKey:key];
if (obj != nil)
{
[NSUserDefaults.standardUserDefaults removeObjectForKey:key];
}
}
else
{
[NSUserDefaults.standardUserDefaults removeObjectForKey:key];
}
return obj;
}
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename
{
return [self openURL:[NSURL fileURLWithPath:filename]];
}
- (IBAction)openDocument:(id)sender
{
NSOpenPanel* panel = [NSOpenPanel new];
NSModalResponse response = [panel runModal];
if ( response == NSModalResponseOK )
{
[self openURL:panel.URL];
}
}
- (BOOL)openURL:(NSURL *)url
{
if ([self.s9xEngine loadROM:url])
{
[self.window makeKeyAndOrderFront:self];
[NSDocumentController.sharedDocumentController noteNewRecentDocumentURL:url];
return YES;
}
return NO;
}
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
{
return !self.isRunningEmulation;
}
@dynamic isRunningEmulation;
- (BOOL)isRunningEmulation
{
return [self.s9xEngine isRunning] && ![self.s9xEngine isPaused];
}
- (IBAction)terminate:(id)sender
{
[self.s9xEngine stop];
[NSApp terminate:sender];
}
- (IBAction)openPrefs:(id)sender
{
if ( self.prefsWindowController == nil )
{
NSWindow *prefsWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100) styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable backing:NSBackingStoreBuffered defer:NO];
self.prefsWindowController = [[NSWindowController alloc] initWithWindow:prefsWindow];
prefsWindow.contentViewController = [[S9xPrefsViewController alloc] initWithNibName:@"S9xPrefsViewController" bundle:nil];
[prefsWindow center];
}
[self.prefsWindowController.window makeKeyAndOrderFront:self];
}
- (void)setVideoMode:(int)videoMode
{
[self.s9xEngine setVideoMode:videoMode];
[NSUserDefaults.standardUserDefaults setObject:@(videoMode) forKey:kVideoModePref];
[NSUserDefaults.standardUserDefaults synchronize];
}
- (void)setShowFPS:(BOOL)showFPS
{
[self.s9xEngine setShowFPS:showFPS];
[NSUserDefaults.standardUserDefaults setObject:@(showFPS) forKey:kShowFPSPref];
[NSUserDefaults.standardUserDefaults synchronize];
}
- (IBAction)resume:(id)sender
{
[self.s9xEngine resume];
}
- (BOOL)handleInput:(S9xJoypadInput *)input fromJoypad:(S9xJoypad *)joypad
{
if (NSApp.keyWindow != nil && NSApp.keyWindow == self.prefsWindowController.window)
{
return [((S9xPrefsViewController *) self.prefsWindowController.contentViewController) handleInput:input fromJoypad:joypad];
}
return NO;
}
@end

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,60 @@
{
"images" : [
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "2x"
},
{
"size" : "32x32",
"idiom" : "mac",
"filename" : "APPL-32.png",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "2x"
},
{
"size" : "128x128",
"idiom" : "mac",
"filename" : "APPL.png",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15400" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15400"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate"/>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
<menuItem title="Snes9x" id="1Xt-HY-uBw">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Snes9x" systemMenu="apple" id="uQy-DD-JDr">
<items>
<menuItem title="About Snes9x" id="5kV-Vb-QxS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW">
<connections>
<action selector="openPrefs:" target="-1" id="MJd-bf-iNU"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
<menuItem title="Services" id="NMo-om-nkz">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
<menuItem title="Hide Snes9x" keyEquivalent="h" id="Olw-nP-bQN">
<connections>
<action selector="hide:" target="-1" id="PnN-Uc-m68"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
</connections>
</menuItem>
<menuItem title="Show All" id="Kd2-mp-pUS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
<menuItem title="Quit Snes9x" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="Voe-Tx-rLC" id="KcN-YT-dDk"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="File" id="dMs-cI-mzQ">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="File" id="bib-Uj-vzu">
<items>
<menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
<connections>
<action selector="openDocument:" target="-1" id="bVn-NM-KNZ"/>
</connections>
</menuItem>
<menuItem title="Open Recent" id="tXI-mr-wws">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
<items>
<menuItem title="Clear Menu" id="vNY-rz-j42">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="clearRecentDocuments:" target="-1" id="Daa-9d-B3U"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
<connections>
<action selector="performClose:" target="-1" id="HmO-Ls-i7Q"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Emulation" id="Kjk-eO-rPI">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Emulation" id="s2F-Pd-YT5">
<items>
<menuItem title="Resume" keyEquivalent="r" id="m8Y-5s-VGC">
<connections>
<action selector="resume:" target="-1" id="jxw-ZM-JXi"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="View" id="H8h-7b-M4v">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="View" id="HyV-fh-RgO">
<items>
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="toggleFullScreen:" target="-1" id="dU3-MA-1Rq"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="aUF-d1-5bR">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
<connections>
<action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="R4o-n2-Eq4">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="wpr-3q-Mcd">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
<items>
<menuItem title="Snes9x Help" keyEquivalent="?" id="FKE-Sm-Kum">
<connections>
<action selector="showHelp:" target="-1" id="y7X-2Q-9no"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
<point key="canvasLocation" x="132" y="154"/>
</menu>
</objects>
</document>

View File

@ -3,7 +3,31 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>English</string> <string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>CFBundleHelpBookFolder</key>
<string>Snes9x Help</string>
<key>CFBundleHelpBookName</key>
<string>Snes9x Help</string>
<key>NSPrincipalClass</key>
<string>S9xApplication</string>
<key>CFBundleDocumentTypes</key> <key>CFBundleDocumentTypes</key>
<array> <array>
<dict> <dict>
@ -159,31 +183,5 @@
<false/> <false/>
</dict> </dict>
</array> </array>
<key>CFBundleExecutable</key>
<string>Snes9x (ppc)</string>
<key>CFBundleGetInfoString</key>
<string>Snes9x 1.60, Copyright 1996-2019 Snes9x developers.</string>
<key>CFBundleHelpBookFolder</key>
<string>Snes9x Help</string>
<key>CFBundleHelpBookName</key>
<string>Snes9x Help</string>
<key>CFBundleIconFile</key>
<string>APPL.icns</string>
<key>CFBundleIdentifier</key>
<string>com.snes9x.macos.snes9x</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Snes9x</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.60</string>
<key>CFBundleSignature</key>
<string>~9X~</string>
<key>CFBundleVersion</key>
<string>1.60</string>
<key>CSResourcesFileMapped</key>
<true/>
</dict> </dict>
</plist> </plist>

View File

@ -0,0 +1,29 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#import <Cocoa/Cocoa.h>
NS_ASSUME_NONNULL_BEGIN
@interface S9xApplication : NSApplication
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,38 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#import "S9xApplication.h"
#import "AppDelegate.h"
@implementation S9xApplication
- (void)sendEvent:(NSEvent *)event
{
if (event.modifierFlags * NSEventModifierFlagCommand && event.type == NSEventTypeKeyUp && ((AppDelegate *)self.delegate).isRunningEmulation)
{
[self.keyWindow sendEvent:event];
}
else
{
[super sendEvent:event];
}
}
@end

View File

@ -0,0 +1,35 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#import <Cocoa/Cocoa.h>
@class S9xJoypadInput;
NS_ASSUME_NONNULL_BEGIN
@interface S9xButtonConfigTextField : NSSearchField<NSSearchFieldDelegate>
@property (nonatomic, assign) CGKeyCode keyCode;
@property (nonatomic, strong, nullable) S9xJoypadInput *joypadInput;
@property (nonatomic, assign) BOOL disableKeyboardInput;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,359 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#include <CoreFoundation/CoreFoundation.h>
#include <Carbon/Carbon.h>
#import "S9xButtonConfigTextField.h"
@implementation S9xButtonConfigTextField
- (void)awakeFromNib
{
self.delegate = self;
self.placeholderString = @"";
[[self cell] setSearchButtonCell:nil];
NSButtonCell *cancelButton = [[self cell] cancelButtonCell];
cancelButton.target = self;
cancelButton.action = @selector(clearSearch:);
}
- (void)setKeyCode:(CGKeyCode)keyCode
{
if (keyCode == (CGKeyCode)-1)
{
_keyCode = keyCode;
self.stringValue = @"";
return;
}
NSString *stringValue = nil;
switch (keyCode)
{
case kVK_Shift:
stringValue = NSLocalizedString(@"Shift", @"");
break;
case kVK_Command:
stringValue = NSLocalizedString(@"Command", @"");
break;
case kVK_Control:
stringValue = NSLocalizedString(@"Control", @"");
break;
case kVK_Option:
stringValue = NSLocalizedString(@"Option", @"");
break;
case kVK_F1:
stringValue = NSLocalizedString(@"F1", @"");
break;
case kVK_F2:
stringValue = NSLocalizedString(@"F2", @"");
break;
case kVK_F3:
stringValue = NSLocalizedString(@"F3", @"");
break;
case kVK_F4:
stringValue = NSLocalizedString(@"F4", @"");
break;
case kVK_F5:
stringValue = NSLocalizedString(@"F5", @"");
break;
case kVK_F6:
stringValue = NSLocalizedString(@"F6", @"");
break;
case kVK_F7:
stringValue = NSLocalizedString(@"F7", @"");
break;
case kVK_F8:
stringValue = NSLocalizedString(@"F8", @"");
break;
case kVK_F9:
stringValue = NSLocalizedString(@"F9", @"");
break;
case kVK_F10:
stringValue = NSLocalizedString(@"F10", @"");
break;
case kVK_F11:
stringValue = NSLocalizedString(@"F11", @"");
break;
case kVK_F12:
stringValue = NSLocalizedString(@"F12", @"");
break;
case kVK_F13:
stringValue = NSLocalizedString(@"F13", @"");
break;
case kVK_F14:
stringValue = NSLocalizedString(@"F14", @"");
break;
case kVK_F15:
stringValue = NSLocalizedString(@"F15", @"");
break;
case kVK_F16:
stringValue = NSLocalizedString(@"F16", @"");
break;
case kVK_F17:
stringValue = NSLocalizedString(@"F17", @"");
break;
case kVK_F18:
stringValue = NSLocalizedString(@"F18", @"");
break;
case kVK_F19:
stringValue = NSLocalizedString(@"F19", @"");
break;
case kVK_F20:
stringValue = NSLocalizedString(@"F20", @"");
break;
case kVK_Delete:
stringValue = NSLocalizedString(@"Delete", @"");
break;
case kVK_ForwardDelete:
stringValue = NSLocalizedString(@"⌦", @"");
break;
case kVK_Home:
stringValue = NSLocalizedString(@"Home", @"");
break;
case kVK_End:
stringValue = NSLocalizedString(@"End", @"");
break;
case kVK_PageUp:
stringValue = NSLocalizedString(@"Page Up", @"");
break;
case kVK_PageDown:
stringValue = NSLocalizedString(@"Page Down", @"");
break;
case kVK_Tab:
stringValue = NSLocalizedString(@"Tab", @"");
break;
case kVK_Space:
stringValue = NSLocalizedString(@"Space", @"");
break;
case kVK_ANSI_KeypadClear:
stringValue = NSLocalizedString(@"Clear", @"");
break;
case kVK_LeftArrow:
stringValue = NSLocalizedString(@"←", @"");
break;
case kVK_RightArrow:
stringValue = NSLocalizedString(@"→", @"");
break;
case kVK_UpArrow:
stringValue = NSLocalizedString(@"↑", @"");
break;
case kVK_DownArrow:
stringValue = NSLocalizedString(@"↓", @"");
break;
case kVK_Return:
stringValue = NSLocalizedString(@"Return", @"");
break;
case kVK_ANSI_KeypadEnter:
stringValue = NSLocalizedString(@"Enter", @"");
break;
case kVK_Escape:
stringValue = NSLocalizedString(@"Escape", @"");
break;
default:
{
TISInputSourceRef keyboard = TISCopyCurrentKeyboardInputSource();
CFDataRef layoutData = (CFDataRef)TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData);
if ( layoutData != NULL )
{
const UCKeyboardLayout *layout = (const UCKeyboardLayout*)CFDataGetBytePtr(layoutData);
UniCharCount maxStringLength = 0xFF;
UniCharCount actualStringLength = 0;
UniChar unicodeString[maxStringLength];
uint32_t deadKeyState = 0;
OSErr status = UCKeyTranslate(layout, keyCode, kUCKeyActionDisplay, kUCKeyTranslateNoDeadKeysBit, LMGetKbdType(), 0, &deadKeyState, maxStringLength, &actualStringLength, unicodeString);
if (status == noErr && actualStringLength > 0)
{
stringValue = [NSString stringWithCharacters:unicodeString length:actualStringLength];
switch (keyCode)
{
case kVK_ANSI_Keypad0:
case kVK_ANSI_Keypad1:
case kVK_ANSI_Keypad2:
case kVK_ANSI_Keypad3:
case kVK_ANSI_Keypad4:
case kVK_ANSI_Keypad5:
case kVK_ANSI_Keypad6:
case kVK_ANSI_Keypad7:
case kVK_ANSI_Keypad8:
case kVK_ANSI_Keypad9:
case kVK_ANSI_KeypadPlus:
case kVK_ANSI_KeypadMinus:
case kVK_ANSI_KeypadDivide:
case kVK_ANSI_KeypadMultiply:
case kVK_ANSI_KeypadEquals:
case kVK_ANSI_KeypadDecimal:
stringValue = [[stringValue stringByAppendingString:@" "] stringByAppendingString:NSLocalizedString(@"(Keypad)", @"")];
break;
}
}
}
}
}
if ( stringValue != nil )
{
stringValue = [[stringValue componentsSeparatedByCharactersInSet:NSCharacterSet.controlCharacterSet] componentsJoinedByString:@""];
stringValue = [[stringValue componentsSeparatedByCharactersInSet:NSCharacterSet.newlineCharacterSet] componentsJoinedByString:@""];
stringValue = [[stringValue componentsSeparatedByCharactersInSet:NSCharacterSet.illegalCharacterSet] componentsJoinedByString:@""];
if ( stringValue.length > 0 )
{
self.stringValue = stringValue.capitalizedString;
[self.window makeFirstResponder:self.window.contentView];
}
}
_keyCode = keyCode;
}
- (void)controlTextDidChange:(NSNotification *)obj
{
self.stringValue = @"";
}
- (void)keyUp:(NSEvent *)event
{
if (!self.disableKeyboardInput )
{
[self setKeyCode:event.keyCode];
}
}
- (void)flagsChanged:(NSEvent *)event
{
if (self.disableKeyboardInput)
{
return;
}
NSEventModifierFlags flags = event.modifierFlags;
if ( flags & NSEventModifierFlagShift )
{
[self setKeyCode:kVK_Shift];
}
else if ( flags & NSEventModifierFlagOption )
{
[self setKeyCode:kVK_Option];
}
else if ( flags & NSEventModifierFlagCommand )
{
[self setKeyCode:kVK_Command];
}
else if ( flags & NSEventModifierFlagControl )
{
[self setKeyCode:kVK_Control];
}
}
- (void)mouseDown:(NSEvent *)event
{
[super mouseDown:event];
[self.currentEditor selectAll:self];
}
- (void)clearSearch:(id)sender
{
self.stringValue = @"";
if (self.disableKeyboardInput)
{
self.joypadInput = nil;
}
else
{
self.keyCode = -1;
}
}
- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector
{
if (self.disableKeyboardInput)
{
return NO;
}
if (commandSelector == @selector(insertTab:))
{
[self setKeyCode:kVK_Tab];
return YES;
}
else if (commandSelector == @selector(cancelOperation:))
{
[self setKeyCode:kVK_Escape];
return YES;
}
return NO;
}
- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor
{
return !self.disableKeyboardInput;
}
@end

View File

@ -0,0 +1,27 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#import <Foundation/Foundation.h>
extern NSString * const kKeyboardPrefs;
extern NSString * const kJoypadInputPrefs;
extern NSString * const kJoypadPlayerPrefs;
extern NSString * const kShowFPSPref;
extern NSString * const kVideoModePref;

View File

@ -0,0 +1,27 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#import "S9xPrefsConstants.h"
NSString * const kKeyboardPrefs = @"KeyboardConfig";
NSString * const kJoypadInputPrefs = @"JoypadInputs";
NSString * const kJoypadPlayerPrefs = @"JoypadPlayers";
NSString * const kShowFPSPref = @"ShowFPS";
NSString * const kVideoModePref = @"VideoMode";

View File

@ -0,0 +1,28 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#import <Cocoa/Cocoa.h>
NS_ASSUME_NONNULL_BEGIN
@interface S9xPrefsViewController : NSViewController<S9xInputDelegate>
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,297 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#import <snes9x_framework/snes9x_framework.h>
#import "AppDelegate.h"
#import "S9xPrefsConstants.h"
#import "S9xPrefsViewController.h"
#import "S9xButtonConfigTextField.h"
@interface S9xPrefsViewController ()
@property (nonatomic, weak) IBOutlet NSPopUpButton *videoModePopup;
@property (nonatomic, weak) IBOutlet NSButton *showFPSCheckbox;
@property (nonatomic, weak) IBOutlet NSPopUpButton *devicePopUp;
@property (nonatomic, weak) IBOutlet NSPopUpButton *playerPopUp;
@end
@implementation S9xPrefsViewController
- (void)awakeFromNib
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
NSUInteger joypadIndex = 0;
for (S9xJoypad *joypad in [appDelegate listJoypads])
{
NSMenuItem *item = [NSMenuItem new];
item.title = joypad.name;
item.tag = joypadIndex++;
item.representedObject = joypad;
[self.devicePopUp.menu addItem:item];
}
[self selectDeviceForPlayer:0];
for (NSView *subview in self.view.subviews)
{
if ( [subview isKindOfClass:[S9xButtonConfigTextField class]] )
{
S9xButtonConfigTextField *field = (S9xButtonConfigTextField *)subview;
[field addObserver:self forKeyPath:@"keyCode" options:NSKeyValueObservingOptionNew context:NULL];
[field addObserver:self forKeyPath:@"joypadInput" options:NSKeyValueObservingOptionNew context:NULL];
}
}
}
- (void)selectDeviceForPlayer:(int8_t)player
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
NSString* joypadKey = [[NSUserDefaults.standardUserDefaults objectForKey:kJoypadPlayerPrefs] objectForKey:@(player).stringValue];
[self.devicePopUp selectItemAtIndex:0];
if (joypadKey != nil)
{
uint32 vendorID = 0;
uint32 productID = 0;
uint32 index = 0;
if ( [appDelegate getValuesFromString:joypadKey vendorID:&vendorID productID:&productID index:&index])
{
S9xJoypad *joypad = [S9xJoypad new];
joypad.vendorID = vendorID;
joypad.productID = productID;
joypad.index = index;
for (NSMenuItem *item in self.devicePopUp.menu.itemArray)
{
if ([joypad isEqual:item.representedObject])
{
[self.devicePopUp selectItem:item];
break;
}
}
}
}
}
- (void)viewDidAppear
{
[super viewDidAppear];
[self.view.window makeFirstResponder:self.view];
[self refresh];
}
- (void)refresh
{
NSUInteger index = MIN([NSUserDefaults.standardUserDefaults integerForKey:kVideoModePref], 1);
[self.videoModePopup selectItemAtIndex:index];
self.showFPSCheckbox.state = [NSUserDefaults.standardUserDefaults boolForKey:kShowFPSPref];
if (self.devicePopUp.selectedItem.tag < 0)
{
NSMutableDictionary<NSNumber *, NSNumber *> *controlsDict = [NSMutableDictionary new];
NSDictionary *keyboardDict = [NSUserDefaults.standardUserDefaults objectForKey:kKeyboardPrefs];
NSInteger playerNum = self.playerPopUp.selectedItem.tag;
for (NSUInteger i = 0; i < kNumButtons; ++i)
{
controlsDict[@(i)] = keyboardDict[@(i + playerNum).stringValue];
}
for (NSView *subview in self.view.subviews)
{
if ([subview isKindOfClass:[S9xButtonConfigTextField class]])
{
S9xButtonConfigTextField *field = (S9xButtonConfigTextField *)subview;
[field removeObserver:self forKeyPath:@"keyCode"];
[field removeObserver:self forKeyPath:@"joypadInput"];
NSNumber *keyCode = controlsDict[@(field.tag)];
field.joypadInput = nil;
if ( keyCode != nil )
{
field.keyCode = keyCode.intValue;
}
else
{
field.keyCode = -1;
}
[field addObserver:self forKeyPath:@"keyCode" options:NSKeyValueObservingOptionNew context:NULL];
[field addObserver:self forKeyPath:@"joypadInput" options:NSKeyValueObservingOptionNew context:NULL];
field.disableKeyboardInput = NO;
}
}
}
else
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
S9xJoypad *joypad = self.devicePopUp.selectedItem.representedObject;
NSString *joypadKey = [appDelegate prefsKeyForVendorID:joypad.vendorID productID:joypad.productID index:joypad.index];
NSDictionary *joypadDIct = [[NSUserDefaults.standardUserDefaults objectForKey:kJoypadInputPrefs] objectForKey:joypadKey];
for (NSView *subview in self.view.subviews)
{
if ([subview isKindOfClass:[S9xButtonConfigTextField class]])
{
S9xButtonConfigTextField *textField = (S9xButtonConfigTextField *)subview;
[textField removeObserver:self forKeyPath:@"keyCode"];
[textField removeObserver:self forKeyPath:@"joypadInput"];
uint32 cookie = 0;
int32 value = 0;
S9xButtonCode buttonCode = (S9xButtonCode)textField.tag;
NSString *inputString = joypadDIct[@(buttonCode).stringValue];
textField.keyCode = -1;
if ([appDelegate getValuesFromString:inputString cookie:&cookie value:&value])
{
S9xJoypadInput *input = [S9xJoypadInput new];
input.cookie = cookie;
input.value = value;
input.buttonCode = buttonCode;
textField.joypadInput = input;
textField.stringValue = [appDelegate labelForVendorID:joypad.vendorID productID:joypad.productID cookie:cookie value:value];
}
else
{
textField.joypadInput = nil;
textField.stringValue = @"";
}
[textField addObserver:self forKeyPath:@"keyCode" options:NSKeyValueObservingOptionNew context:NULL];
[textField addObserver:self forKeyPath:@"joypadInput" options:NSKeyValueObservingOptionNew context:NULL];
textField.disableKeyboardInput = YES;
}
}
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
if ([keyPath isEqualToString:@"keyCode"])
{
S9xButtonConfigTextField *field = (S9xButtonConfigTextField *)object;
S9xButtonCode buttonCode = (S9xButtonCode)field.tag;
uint16_t keyCode = field.keyCode;
int8_t player = self.playerPopUp.selectedItem.tag;
if (keyCode != (CGKeyCode)-1)
{
[((AppDelegate *) NSApp.delegate) setButtonCode:buttonCode forKeyCode:keyCode player:player];
}
else
{
[((AppDelegate *) NSApp.delegate) clearButton:buttonCode forPlayer:player];
}
[NSUserDefaults.standardUserDefaults synchronize];
[self refresh];
}
else if ( [keyPath isEqualToString:@"joypadInput"])
{
S9xButtonConfigTextField *field = (S9xButtonConfigTextField *)object;
S9xButtonCode buttonCode = (S9xButtonCode)field.tag;
S9xJoypad *joypad = self.devicePopUp.selectedItem.representedObject;
if ([joypad isKindOfClass:[S9xJoypad class]])
{
S9xJoypadInput *input = field.joypadInput;
if (input != nil)
{
[((AppDelegate *)NSApp.delegate) setButton:buttonCode forVendorID:joypad.vendorID productID:joypad.productID index:joypad.index cookie:input.cookie value:input.value];
}
else
{
[((AppDelegate *)NSApp.delegate) clearJoypadForVendorID:joypad.vendorID productID:joypad.productID index:joypad.index buttonCode:buttonCode];
}
}
[NSUserDefaults.standardUserDefaults synchronize];
[self refresh];
}
}
- (IBAction)playerDropdownChanged:(NSPopUpButton *)sender
{
[self selectDeviceForPlayer:sender.selectedTag];
[self refresh];
}
- (IBAction)deviceDropdownChanged:(NSPopUpButton *)sender
{
if (sender.selectedTag >= 0)
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
S9xJoypad *joypad = sender.selectedItem.representedObject;
[appDelegate setPlayer:self.playerPopUp.selectedTag forVendorID:joypad.vendorID productID:joypad.productID index:joypad.index];
[NSUserDefaults.standardUserDefaults synchronize];
}
[self refresh];
}
- (IBAction)showFPS:(NSButton *)sender
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
[appDelegate setShowFPS:sender.state == NSOnState];
}
- (IBAction)setVideoMode:(NSPopUpButton *)sender
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
[appDelegate setVideoMode:(int)sender.selectedTag];
}
- (BOOL)handleInput:(S9xJoypadInput *)input fromJoypad:(S9xJoypad *)joypad
{
id firstResponder = self.view.window.firstResponder;
if ([firstResponder respondsToSelector:@selector(isFieldEditor)] && [firstResponder isFieldEditor])
{
firstResponder = [firstResponder delegate];
}
if ([firstResponder respondsToSelector:@selector(setJoypadInput:)])
{
S9xJoypad *currentJoypad = self.devicePopUp.selectedItem.representedObject;
if ([joypad isEqual:currentJoypad])
{
[firstResponder setJoypadInput:input];
return YES;
}
}
return NO;
}
@end

View File

@ -0,0 +1,817 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15400" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15400"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="S9xPrefsViewController">
<connections>
<outlet property="devicePopUp" destination="mJx-JF-xDg" id="jLF-8u-Xwv"/>
<outlet property="playerPopUp" destination="hfx-Lg-t9P" id="pJR-nP-Ajt"/>
<outlet property="showFPSCheckbox" destination="M0c-Sj-o1i" id="4YI-cQ-MCK"/>
<outlet property="videoModePopup" destination="qNi-B0-E49" id="X4h-CV-IgC"/>
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="Hz6-mo-xeY">
<rect key="frame" x="0.0" y="0.0" width="507" height="574"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rxW-aA-Bai">
<rect key="frame" x="18" y="538" width="191" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Video Mode (Requires Restart)" id="XoT-95-aIF">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="qNi-B0-E49">
<rect key="frame" x="213" y="532" width="85" height="25"/>
<popUpButtonCell key="cell" type="push" title="Blocky" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Xg7-hz-RRs" id="IRO-Ia-Tlm">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="VtI-7w-Yps">
<items>
<menuItem title="Blocky" state="on" id="Xg7-hz-RRs"/>
<menuItem title="Smooth" tag="2" id="ucR-ef-Wfk"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<action selector="setVideoMode:" target="-2" id="oj8-pk-Kdg"/>
</connections>
</popUpButton>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hfx-Lg-t9P">
<rect key="frame" x="18" y="503" width="472" height="25"/>
<popUpButtonCell key="cell" type="push" title="Player 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Mes-ZE-LOG" id="3Oa-7I-2cH">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="nds-U1-9Cm">
<items>
<menuItem title="Player 1" state="on" id="Mes-ZE-LOG"/>
<menuItem title="Player 2" tag="1" id="AWG-xK-l3f"/>
<menuItem title="Player 3" tag="2" id="jSq-tK-TKM"/>
<menuItem title="Player 4" tag="3" id="hmJ-yy-u6L"/>
<menuItem title="Player 5" tag="4" id="4J1-GS-DgW"/>
<menuItem title="Player 6" tag="5" id="UH1-NG-PB6"/>
<menuItem title="Player 7" tag="6" id="DjI-Q2-ZNu"/>
<menuItem title="Player 8" tag="7" id="6Z7-mO-SMy"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<action selector="playerDropdownChanged:" target="-2" id="P4K-gg-QUK"/>
</connections>
</popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="qMp-14-9zW">
<rect key="frame" x="18" y="443" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Up" id="hua-jM-68w">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2BM-Lt-WwR">
<rect key="frame" x="18" y="413" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Down" id="z7r-rj-abc">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="biW-Zy-9NZ">
<rect key="frame" x="18" y="383" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Left" id="zD3-HS-vYg">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rsc-8R-cwh">
<rect key="frame" x="18" y="353" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Right" id="m1L-Ha-tjV">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yHT-3q-ctP">
<rect key="frame" x="18" y="323" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="A" id="AOM-k9-LVv">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="WcI-SC-fZV">
<rect key="frame" x="18" y="293" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="B" id="afx-UX-ra7">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="atg-Fg-IgS">
<rect key="frame" x="18" y="263" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="X" id="R4J-4s-qIx">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="NeB-Rh-CKs">
<rect key="frame" x="18" y="233" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Y" id="Nho-ku-fUk">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Rz0-Kg-nHG">
<rect key="frame" x="18" y="203" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="L" id="jvi-9B-mJS">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="AiU-u8-z9t">
<rect key="frame" x="18" y="173" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="R" id="ckb-YM-tFe">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3Cb-Ht-JzJ">
<rect key="frame" x="18" y="143" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Start" id="oqQ-e5-KNH">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ISU-xt-cZa">
<rect key="frame" x="18" y="113" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Select" id="RW3-fW-YAS">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="c4Z-r1-O38">
<rect key="frame" x="18" y="83" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Function" id="xbY-Z6-sBG">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Rsg-HQ-Cig">
<rect key="frame" x="18" y="53" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Alt" id="nKE-jO-OCz">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="dL6-2Y-CIz">
<rect key="frame" x="18" y="23" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Turbo Control" id="i08-K8-ZqE">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="drA-2C-LPt">
<rect key="frame" x="230" y="443" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Escape" id="tle-rH-QLe">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5DP-Qu-lS2">
<rect key="frame" x="230" y="413" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Freeze" id="HsC-E3-aUn">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jQs-eL-Df4">
<rect key="frame" x="230" y="383" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Defrost" id="LO9-bN-27u">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="M0c-Sj-o1i">
<rect key="frame" x="406" y="537" width="83" height="18"/>
<buttonCell key="cell" type="check" title="Show FPS" bezelStyle="regularSquare" imagePosition="left" inset="2" id="l8L-ZQ-K9n">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showFPS:" target="-2" id="CM2-bf-aFb"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="TuE-fA-Shh">
<rect key="frame" x="230" y="353" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Screenshot" id="XrV-eO-k3u">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jHT-Uw-MKM">
<rect key="frame" x="230" y="323" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Fast Forward" id="IrR-8T-GsO">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="R5Q-JF-7P7">
<rect key="frame" x="230" y="293" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Increase FF Speed" id="DL5-qE-hMa">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="O9g-UA-3gp">
<rect key="frame" x="230" y="263" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Decrease FF Speed" id="JoH-8A-HTb">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vrB-v6-gvS">
<rect key="frame" x="230" y="233" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Super Scope Turbo" id="5Ok-p3-jsW">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="RXV-hd-YH8">
<rect key="frame" x="230" y="203" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Super Scope Cursor" id="bLP-cT-3YD">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fG8-lF-YYW">
<rect key="frame" x="230" y="173" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Super Scope Off Screen" id="e9h-qE-jme">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eyk-QN-lkH">
<rect key="frame" x="230" y="143" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Pause Soper Scope" id="5op-LV-kgt">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0xy-5S-ffb">
<rect key="frame" x="230" y="113" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Left Mouse" id="hBs-n4-TD6">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jOm-aT-92f">
<rect key="frame" x="230" y="83" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Right Mouse" id="PMa-Fr-3vd">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ymc-Xn-VtU">
<rect key="frame" x="230" y="53" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Save SPC" id="Yvu-uO-lMI">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mJx-JF-xDg">
<rect key="frame" x="18" y="474" width="472" height="25"/>
<popUpButtonCell key="cell" type="push" title="Keyboard" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="-1" imageScaling="proportionallyDown" inset="2" selectedItem="Cs2-1w-ccm" id="ui9-4e-0EL">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="vSY-DD-mp3">
<items>
<menuItem title="Keyboard" state="on" tag="-1" id="Cs2-1w-ccm"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<action selector="deviceDropdownChanged:" target="-2" id="oH3-xl-IZF"/>
</connections>
</popUpButton>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="1" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5wn-WM-n7f" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="410" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="6tU-6G-dKy"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="k5A-MS-Z6b">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="2" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Pdg-iO-Rlv" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="380" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="Vzs-rb-iSz"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="2uN-kX-Tga">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="i6K-Iu-xdk" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="440" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="B3A-lY-BCn"/>
<constraint firstAttribute="width" constant="100" id="TGv-i2-qc7"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="kfN-fb-kJk">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="3" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="W7s-0d-JNo" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="350" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="KgL-oM-FNL"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="nDY-Wf-kMT">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="7" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="56u-eS-Y7s" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="320" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="old-cu-PoH"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="wpF-K9-uGS">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="6" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xib-ad-dgH" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="260" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="nCJ-u5-vpC"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="P74-cT-Hhv">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="4" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lSq-25-AV2" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="230" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="Zwq-yn-TeE"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="hXa-pS-qJq">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="5" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6dg-5z-gNX" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="290" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="Qe9-et-5QN"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="jfT-jr-LeY"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="IJx-NV-DIi">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="8" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5Ro-Ix-JD5" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="200" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="Jls-qj-Gt0"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="3A1-Qy-pvY">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="9" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fkh-aT-XE9" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="170" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="vbp-eP-ql6"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="9ih-Vg-mrB">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="11" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hLf-i4-NRV" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="110" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="3XK-UH-gXU"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="nlX-ww-ZuR">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="21" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SSJ-4e-Tc8" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="80" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="jbE-Yf-hDQ"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="gvL-GU-9rC">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="10" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ycZ-re-pMx" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="140" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="XTE-Jx-pv7"/>
<constraint firstAttribute="width" constant="100" id="qte-MS-3PL"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="Pdd-Ps-WDJ">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="22" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rX2-Wj-CDJ" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="50" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="mYj-MI-dHJ"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="2ey-x8-4NN">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="26" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="r5O-6f-xdH" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="20" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="0QT-Md-0M0"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="C2T-pv-auB">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="13" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0FY-cv-M9B" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="410" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="xmT-dz-x8T"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="W5m-b8-Ljs">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="14" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Fve-dp-udd" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="380" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="l23-fI-CtT"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="tn1-Kx-fp1">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="25" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ns3-zZ-EQY" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="440" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="Hvr-RF-2d2"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="ILE-7H-7um"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="1UX-yF-wRM">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="15" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GDm-WA-rkG" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="350" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="B4h-mm-FkB"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="0YR-us-6Qy">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="12" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HIj-cE-Twd" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="320" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="IEA-AN-TmA"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="4hD-Qo-n6n">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="23" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VRq-kT-wkC" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="260" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="79e-XA-N79"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="zEb-u6-7A0">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="17" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yHB-42-ebc" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="230" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="saj-Wb-IdB"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="GMG-pM-ni9">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="24" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TIz-bI-n89" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="290" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="OHA-S7-m2g"/>
<constraint firstAttribute="width" constant="100" id="vKB-Bb-kJu"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="IRI-9H-J9c">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="19" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="E3S-mU-OmJ" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="200" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="ayN-Z9-uyh"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="rM5-vB-rnj">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="20" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Lw1-zP-Vdy" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="170" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="tyK-xj-HxC"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="eWo-k0-67t">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="27" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="S5E-xU-QAK" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="110" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="JGe-qf-ind"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="TpE-Vu-cmT">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="28" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WCt-Ri-ndL" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="80" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="khS-Ng-mZK"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="n7S-b5-pPm">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="18" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eZA-Af-a2e" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="140" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="LjM-MK-DCE"/>
<constraint firstAttribute="width" constant="100" id="OO3-Rg-dMj"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="9dt-yN-DB1">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="16" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iZL-4Q-g2k" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="50" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="VOg-Zt-Sna"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="RUv-v1-sy4">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
</subviews>
<constraints>
<constraint firstItem="lSq-25-AV2" firstAttribute="leading" secondItem="NeB-Rh-CKs" secondAttribute="trailing" constant="8" id="06f-oZ-gc9"/>
<constraint firstItem="eyk-QN-lkH" firstAttribute="width" secondItem="0xy-5S-ffb" secondAttribute="width" id="0BG-4g-olJ"/>
<constraint firstItem="5wn-WM-n7f" firstAttribute="top" secondItem="i6K-Iu-xdk" secondAttribute="bottom" constant="8" id="0pz-eS-OKy"/>
<constraint firstItem="biW-Zy-9NZ" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="168-h5-GLY"/>
<constraint firstItem="biW-Zy-9NZ" firstAttribute="width" secondItem="rsc-8R-cwh" secondAttribute="width" id="1Ec-Bs-A10"/>
<constraint firstItem="jHT-Uw-MKM" firstAttribute="leading" secondItem="R5Q-JF-7P7" secondAttribute="leading" id="1TJ-hk-cUg"/>
<constraint firstItem="Lw1-zP-Vdy" firstAttribute="firstBaseline" secondItem="fG8-lF-YYW" secondAttribute="firstBaseline" id="1as-cC-yzO"/>
<constraint firstItem="S5E-xU-QAK" firstAttribute="top" secondItem="eZA-Af-a2e" secondAttribute="bottom" constant="8" id="1ee-ws-w0M"/>
<constraint firstItem="3Cb-Ht-JzJ" firstAttribute="width" secondItem="ISU-xt-cZa" secondAttribute="width" id="1ue-OI-XNP"/>
<constraint firstItem="qMp-14-9zW" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="2ef-fb-3h5"/>
<constraint firstItem="TIz-bI-n89" firstAttribute="leading" secondItem="R5Q-JF-7P7" secondAttribute="trailing" constant="8" id="2hW-Ue-Vsp"/>
<constraint firstItem="GDm-WA-rkG" firstAttribute="firstBaseline" secondItem="TuE-fA-Shh" secondAttribute="firstBaseline" id="42O-Cs-57E"/>
<constraint firstItem="WcI-SC-fZV" firstAttribute="width" secondItem="atg-Fg-IgS" secondAttribute="width" id="4g4-85-hQA"/>
<constraint firstItem="ycZ-re-pMx" firstAttribute="leading" secondItem="3Cb-Ht-JzJ" secondAttribute="trailing" constant="8" id="4gJ-MX-zP2"/>
<constraint firstItem="eZA-Af-a2e" firstAttribute="top" secondItem="Lw1-zP-Vdy" secondAttribute="bottom" constant="8" id="5TI-QI-4q6"/>
<constraint firstItem="c4Z-r1-O38" firstAttribute="width" secondItem="Rsg-HQ-Cig" secondAttribute="width" id="5dc-cT-5xJ"/>
<constraint firstItem="yHT-3q-ctP" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="69R-sL-5SF"/>
<constraint firstItem="Lw1-zP-Vdy" firstAttribute="leading" secondItem="fG8-lF-YYW" secondAttribute="trailing" constant="8" id="76v-dF-nMk"/>
<constraint firstItem="fG8-lF-YYW" firstAttribute="leading" secondItem="eyk-QN-lkH" secondAttribute="leading" id="7v6-7P-4kI"/>
<constraint firstItem="5wn-WM-n7f" firstAttribute="firstBaseline" secondItem="2BM-Lt-WwR" secondAttribute="firstBaseline" id="8Aa-9s-wDv"/>
<constraint firstItem="HIj-cE-Twd" firstAttribute="firstBaseline" secondItem="jHT-Uw-MKM" secondAttribute="firstBaseline" id="8K4-J6-7Ln"/>
<constraint firstItem="Pdg-iO-Rlv" firstAttribute="top" secondItem="5wn-WM-n7f" secondAttribute="bottom" constant="8" id="94J-2J-YaO"/>
<constraint firstItem="iZL-4Q-g2k" firstAttribute="firstBaseline" secondItem="Ymc-Xn-VtU" secondAttribute="firstBaseline" id="9It-Ku-20r"/>
<constraint firstItem="56u-eS-Y7s" firstAttribute="firstBaseline" secondItem="yHT-3q-ctP" secondAttribute="firstBaseline" id="9O2-n7-6FK"/>
<constraint firstItem="0FY-cv-M9B" firstAttribute="leading" secondItem="5DP-Qu-lS2" secondAttribute="trailing" constant="8" id="9Os-Qg-zY5"/>
<constraint firstItem="drA-2C-LPt" firstAttribute="leading" secondItem="i6K-Iu-xdk" secondAttribute="trailing" constant="20" id="Aeq-Py-t3S"/>
<constraint firstItem="Rsg-HQ-Cig" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="Aj6-EC-8k6"/>
<constraint firstItem="WCt-Ri-ndL" firstAttribute="leading" secondItem="jOm-aT-92f" secondAttribute="trailing" constant="8" id="BiA-bF-aa5"/>
<constraint firstItem="S5E-xU-QAK" firstAttribute="firstBaseline" secondItem="0xy-5S-ffb" secondAttribute="firstBaseline" id="C8b-74-452"/>
<constraint firstItem="eZA-Af-a2e" firstAttribute="firstBaseline" secondItem="eyk-QN-lkH" secondAttribute="firstBaseline" id="CNE-YW-lQs"/>
<constraint firstItem="r5O-6f-xdH" firstAttribute="leading" secondItem="dL6-2Y-CIz" secondAttribute="trailing" constant="8" id="Cb7-fX-o5V"/>
<constraint firstItem="VRq-kT-wkC" firstAttribute="firstBaseline" secondItem="O9g-UA-3gp" secondAttribute="firstBaseline" id="DNz-VN-dnq"/>
<constraint firstItem="SSJ-4e-Tc8" firstAttribute="firstBaseline" secondItem="c4Z-r1-O38" secondAttribute="firstBaseline" id="Dfe-L2-A5d"/>
<constraint firstItem="56u-eS-Y7s" firstAttribute="top" secondItem="W7s-0d-JNo" secondAttribute="bottom" constant="8" id="DgW-BJ-cTD"/>
<constraint firstItem="eyk-QN-lkH" firstAttribute="leading" secondItem="0xy-5S-ffb" secondAttribute="leading" id="DoA-iC-K2h"/>
<constraint firstItem="SSJ-4e-Tc8" firstAttribute="top" secondItem="hLf-i4-NRV" secondAttribute="bottom" constant="8" id="DpQ-z0-7bk"/>
<constraint firstItem="AiU-u8-z9t" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="DuJ-xv-SYs"/>
<constraint firstItem="Fve-dp-udd" firstAttribute="leading" secondItem="jQs-eL-Df4" secondAttribute="trailing" constant="8" id="ERu-oo-Fo3"/>
<constraint firstItem="NeB-Rh-CKs" firstAttribute="width" secondItem="Rz0-Kg-nHG" secondAttribute="width" id="Elw-OX-aVc"/>
<constraint firstItem="yHB-42-ebc" firstAttribute="firstBaseline" secondItem="vrB-v6-gvS" secondAttribute="firstBaseline" id="F14-1E-cTk"/>
<constraint firstItem="VRq-kT-wkC" firstAttribute="top" secondItem="TIz-bI-n89" secondAttribute="bottom" constant="8" id="FAT-MC-j2R"/>
<constraint firstItem="5Ro-Ix-JD5" firstAttribute="top" secondItem="lSq-25-AV2" secondAttribute="bottom" constant="8" id="FTG-52-WZK"/>
<constraint firstAttribute="trailing" secondItem="mJx-JF-xDg" secondAttribute="trailing" constant="20" id="FjE-V8-WQf"/>
<constraint firstItem="0xy-5S-ffb" firstAttribute="leading" secondItem="jOm-aT-92f" secondAttribute="leading" id="FnI-WM-zIE"/>
<constraint firstItem="56u-eS-Y7s" firstAttribute="leading" secondItem="yHT-3q-ctP" secondAttribute="trailing" constant="8" id="FuE-hi-SKb"/>
<constraint firstItem="jOm-aT-92f" firstAttribute="width" secondItem="Ymc-Xn-VtU" secondAttribute="width" id="GAQ-Ss-XPz"/>
<constraint firstItem="TIz-bI-n89" firstAttribute="top" secondItem="HIj-cE-Twd" secondAttribute="bottom" constant="8" id="GIp-2p-zxM"/>
<constraint firstItem="r5O-6f-xdH" firstAttribute="top" secondItem="rX2-Wj-CDJ" secondAttribute="bottom" constant="8" id="GUg-cU-Mdi"/>
<constraint firstItem="NeB-Rh-CKs" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="Gvp-Gk-jnY"/>
<constraint firstItem="hfx-Lg-t9P" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="HDg-WG-2Oj"/>
<constraint firstItem="Ns3-zZ-EQY" firstAttribute="firstBaseline" secondItem="drA-2C-LPt" secondAttribute="firstBaseline" id="I5P-lB-vVE"/>
<constraint firstAttribute="trailing" secondItem="hfx-Lg-t9P" secondAttribute="trailing" constant="20" id="IUn-oP-elS"/>
<constraint firstItem="Pdg-iO-Rlv" firstAttribute="firstBaseline" secondItem="biW-Zy-9NZ" secondAttribute="firstBaseline" id="Iw8-MZ-gXl"/>
<constraint firstItem="xib-ad-dgH" firstAttribute="firstBaseline" secondItem="atg-Fg-IgS" secondAttribute="firstBaseline" id="JUk-Fe-nnv"/>
<constraint firstItem="mJx-JF-xDg" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="KLG-ZJ-Qep"/>
<constraint firstItem="r5O-6f-xdH" firstAttribute="firstBaseline" secondItem="dL6-2Y-CIz" secondAttribute="firstBaseline" id="KwJ-iX-Lem"/>
<constraint firstItem="i6K-Iu-xdk" firstAttribute="top" secondItem="mJx-JF-xDg" secondAttribute="bottom" constant="15" id="L3y-MX-53u"/>
<constraint firstItem="rX2-Wj-CDJ" firstAttribute="leading" secondItem="Rsg-HQ-Cig" secondAttribute="trailing" constant="8" id="L8E-dg-fZy"/>
<constraint firstItem="O9g-UA-3gp" firstAttribute="width" secondItem="vrB-v6-gvS" secondAttribute="width" id="Lfb-33-q2U"/>
<constraint firstItem="6dg-5z-gNX" firstAttribute="firstBaseline" secondItem="WcI-SC-fZV" secondAttribute="firstBaseline" id="MHx-P2-7u9"/>
<constraint firstItem="O9g-UA-3gp" firstAttribute="leading" secondItem="vrB-v6-gvS" secondAttribute="leading" id="MQQ-jz-tfP"/>
<constraint firstItem="jOm-aT-92f" firstAttribute="leading" secondItem="Ymc-Xn-VtU" secondAttribute="leading" id="Ne8-17-j3I"/>
<constraint firstItem="ycZ-re-pMx" firstAttribute="top" secondItem="fkh-aT-XE9" secondAttribute="bottom" constant="8" id="NfM-lU-BGG"/>
<constraint firstItem="SSJ-4e-Tc8" firstAttribute="leading" secondItem="c4Z-r1-O38" secondAttribute="trailing" constant="8" id="NxT-Rc-8Yb"/>
<constraint firstItem="TIz-bI-n89" firstAttribute="firstBaseline" secondItem="R5Q-JF-7P7" secondAttribute="firstBaseline" id="Oql-bB-XA7"/>
<constraint firstItem="Rz0-Kg-nHG" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="P8J-kI-F1j"/>
<constraint firstItem="jHT-Uw-MKM" firstAttribute="width" secondItem="R5Q-JF-7P7" secondAttribute="width" id="PQg-0q-7tB"/>
<constraint firstItem="GDm-WA-rkG" firstAttribute="leading" secondItem="TuE-fA-Shh" secondAttribute="trailing" constant="8" id="PlS-Sb-BJl"/>
<constraint firstItem="RXV-hd-YH8" firstAttribute="width" secondItem="fG8-lF-YYW" secondAttribute="width" id="Qkw-4J-1Xs"/>
<constraint firstItem="E3S-mU-OmJ" firstAttribute="firstBaseline" secondItem="RXV-hd-YH8" secondAttribute="firstBaseline" id="Qzk-e3-HIm"/>
<constraint firstAttribute="trailing" secondItem="hfx-Lg-t9P" secondAttribute="trailing" constant="20" id="SUL-1F-PVw"/>
<constraint firstItem="lSq-25-AV2" firstAttribute="top" secondItem="xib-ad-dgH" secondAttribute="bottom" constant="8" id="Scm-FO-oTB"/>
<constraint firstItem="ISU-xt-cZa" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="Spb-nj-cDC"/>
<constraint firstItem="M0c-Sj-o1i" firstAttribute="firstBaseline" secondItem="qNi-B0-E49" secondAttribute="firstBaseline" id="T6e-qJ-gZ3"/>
<constraint firstItem="RXV-hd-YH8" firstAttribute="leading" secondItem="fG8-lF-YYW" secondAttribute="leading" id="TNu-0d-7hY"/>
<constraint firstItem="rX2-Wj-CDJ" firstAttribute="top" secondItem="SSJ-4e-Tc8" secondAttribute="bottom" constant="8" id="TVc-Gm-Z9C"/>
<constraint firstItem="Rz0-Kg-nHG" firstAttribute="width" secondItem="AiU-u8-z9t" secondAttribute="width" id="TuG-69-3ZZ"/>
<constraint firstItem="hfx-Lg-t9P" firstAttribute="top" secondItem="qNi-B0-E49" secondAttribute="bottom" constant="8" id="U1a-EU-qRX"/>
<constraint firstItem="S5E-xU-QAK" firstAttribute="leading" secondItem="0xy-5S-ffb" secondAttribute="trailing" constant="8" id="V45-bc-c8o"/>
<constraint firstItem="0FY-cv-M9B" firstAttribute="firstBaseline" secondItem="5DP-Qu-lS2" secondAttribute="firstBaseline" id="VjF-HO-8el"/>
<constraint firstItem="atg-Fg-IgS" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="W43-Jm-i2I"/>
<constraint firstItem="yHB-42-ebc" firstAttribute="leading" secondItem="vrB-v6-gvS" secondAttribute="trailing" constant="8" id="WC4-cY-SXd"/>
<constraint firstItem="qMp-14-9zW" firstAttribute="width" secondItem="2BM-Lt-WwR" secondAttribute="width" id="Wmc-Lc-tZx"/>
<constraint firstItem="rX2-Wj-CDJ" firstAttribute="firstBaseline" secondItem="Rsg-HQ-Cig" secondAttribute="firstBaseline" id="X7F-Js-Nra"/>
<constraint firstItem="fkh-aT-XE9" firstAttribute="firstBaseline" secondItem="AiU-u8-z9t" secondAttribute="firstBaseline" id="XMx-Tw-IXd"/>
<constraint firstItem="Pdg-iO-Rlv" firstAttribute="leading" secondItem="biW-Zy-9NZ" secondAttribute="trailing" constant="8" id="Y6V-wt-Xb5"/>
<constraint firstItem="Rsg-HQ-Cig" firstAttribute="width" secondItem="dL6-2Y-CIz" secondAttribute="width" id="Y72-0k-X9j"/>
<constraint firstItem="VRq-kT-wkC" firstAttribute="leading" secondItem="O9g-UA-3gp" secondAttribute="trailing" constant="8" id="YQZ-ll-Hgx"/>
<constraint firstItem="rsc-8R-cwh" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="Yar-cB-3Qx"/>
<constraint firstAttribute="bottom" secondItem="r5O-6f-xdH" secondAttribute="bottom" constant="20" id="ZFe-ts-Cxn"/>
<constraint firstItem="5Ro-Ix-JD5" firstAttribute="leading" secondItem="Rz0-Kg-nHG" secondAttribute="trailing" constant="8" id="ZT8-H1-D7g"/>
<constraint firstItem="vrB-v6-gvS" firstAttribute="leading" secondItem="RXV-hd-YH8" secondAttribute="leading" id="ZkV-M1-Yc3"/>
<constraint firstItem="2BM-Lt-WwR" firstAttribute="width" secondItem="biW-Zy-9NZ" secondAttribute="width" id="a8L-cO-AXv"/>
<constraint firstItem="qNi-B0-E49" firstAttribute="firstBaseline" secondItem="rxW-aA-Bai" secondAttribute="firstBaseline" id="aRI-Fh-eSE"/>
<constraint firstItem="Fve-dp-udd" firstAttribute="firstBaseline" secondItem="jQs-eL-Df4" secondAttribute="firstBaseline" id="aa9-Eu-wYV"/>
<constraint firstItem="lSq-25-AV2" firstAttribute="firstBaseline" secondItem="NeB-Rh-CKs" secondAttribute="firstBaseline" id="bGA-rb-hEr"/>
<constraint firstItem="5DP-Qu-lS2" firstAttribute="leading" secondItem="jQs-eL-Df4" secondAttribute="leading" id="cST-Al-uuC"/>
<constraint firstItem="hLf-i4-NRV" firstAttribute="leading" secondItem="ISU-xt-cZa" secondAttribute="trailing" constant="8" id="dBX-fh-DCK"/>
<constraint firstItem="drA-2C-LPt" firstAttribute="width" secondItem="5DP-Qu-lS2" secondAttribute="width" id="dXn-LW-UPX"/>
<constraint firstItem="0xy-5S-ffb" firstAttribute="width" secondItem="jOm-aT-92f" secondAttribute="width" id="dYD-sh-m5R"/>
<constraint firstItem="TuE-fA-Shh" firstAttribute="width" secondItem="jHT-Uw-MKM" secondAttribute="width" id="dy3-xX-glM"/>
<constraint firstItem="WCt-Ri-ndL" firstAttribute="firstBaseline" secondItem="jOm-aT-92f" secondAttribute="firstBaseline" id="eRT-n8-fY0"/>
<constraint firstItem="mJx-JF-xDg" firstAttribute="top" secondItem="hfx-Lg-t9P" secondAttribute="bottom" constant="8" id="erO-qQ-EkZ"/>
<constraint firstItem="3Cb-Ht-JzJ" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="f8t-7g-9tF"/>
<constraint firstItem="W7s-0d-JNo" firstAttribute="leading" secondItem="rsc-8R-cwh" secondAttribute="trailing" constant="8" id="ffY-aY-doh"/>
<constraint firstItem="qNi-B0-E49" firstAttribute="leading" secondItem="rxW-aA-Bai" secondAttribute="trailing" constant="8" id="fiq-A8-Zvj"/>
<constraint firstItem="rsc-8R-cwh" firstAttribute="width" secondItem="yHT-3q-ctP" secondAttribute="width" id="frA-S7-zPQ"/>
<constraint firstItem="E3S-mU-OmJ" firstAttribute="top" secondItem="yHB-42-ebc" secondAttribute="bottom" constant="8" id="fwb-mN-WZp"/>
<constraint firstItem="W7s-0d-JNo" firstAttribute="top" secondItem="Pdg-iO-Rlv" secondAttribute="bottom" constant="8" id="gsZ-9n-duu"/>
<constraint firstItem="fkh-aT-XE9" firstAttribute="top" secondItem="5Ro-Ix-JD5" secondAttribute="bottom" constant="8" id="h0C-jn-NJC"/>
<constraint firstItem="c4Z-r1-O38" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="hJV-iW-3K0"/>
<constraint firstItem="ycZ-re-pMx" firstAttribute="firstBaseline" secondItem="3Cb-Ht-JzJ" secondAttribute="firstBaseline" id="i7O-Pd-BBi"/>
<constraint firstItem="drA-2C-LPt" firstAttribute="leading" secondItem="5DP-Qu-lS2" secondAttribute="leading" id="iFX-tU-zbX"/>
<constraint firstItem="TuE-fA-Shh" firstAttribute="leading" secondItem="jHT-Uw-MKM" secondAttribute="leading" id="iuz-gv-oL8"/>
<constraint firstItem="i6K-Iu-xdk" firstAttribute="firstBaseline" secondItem="qMp-14-9zW" secondAttribute="firstBaseline" id="jOJ-6W-gyj"/>
<constraint firstItem="R5Q-JF-7P7" firstAttribute="leading" secondItem="O9g-UA-3gp" secondAttribute="leading" id="jvo-2N-1c6"/>
<constraint firstItem="ISU-xt-cZa" firstAttribute="width" secondItem="c4Z-r1-O38" secondAttribute="width" id="k5K-QA-Kdy"/>
<constraint firstItem="hLf-i4-NRV" firstAttribute="firstBaseline" secondItem="ISU-xt-cZa" secondAttribute="firstBaseline" id="k6v-Nf-0Ns"/>
<constraint firstItem="Ns3-zZ-EQY" firstAttribute="centerY" secondItem="i6K-Iu-xdk" secondAttribute="centerY" id="k7c-VC-F2q"/>
<constraint firstItem="xib-ad-dgH" firstAttribute="leading" secondItem="atg-Fg-IgS" secondAttribute="trailing" constant="8" id="kJe-AZ-BHz"/>
<constraint firstItem="eZA-Af-a2e" firstAttribute="leading" secondItem="eyk-QN-lkH" secondAttribute="trailing" constant="8" id="kY5-nM-9bS"/>
<constraint firstItem="Ns3-zZ-EQY" firstAttribute="leading" secondItem="drA-2C-LPt" secondAttribute="trailing" constant="8" id="lk5-8o-ywx"/>
<constraint firstItem="xib-ad-dgH" firstAttribute="top" secondItem="6dg-5z-gNX" secondAttribute="bottom" constant="8" id="lkr-rc-E9z"/>
<constraint firstItem="iZL-4Q-g2k" firstAttribute="top" secondItem="WCt-Ri-ndL" secondAttribute="bottom" constant="8" id="mqw-LZ-0G5"/>
<constraint firstItem="Fve-dp-udd" firstAttribute="top" secondItem="0FY-cv-M9B" secondAttribute="bottom" constant="8" id="nH6-Hj-btT"/>
<constraint firstItem="HIj-cE-Twd" firstAttribute="leading" secondItem="jHT-Uw-MKM" secondAttribute="trailing" constant="8" id="nKL-DQ-J82"/>
<constraint firstItem="jQs-eL-Df4" firstAttribute="leading" secondItem="TuE-fA-Shh" secondAttribute="leading" id="nb5-yD-0IC"/>
<constraint firstItem="fkh-aT-XE9" firstAttribute="leading" secondItem="AiU-u8-z9t" secondAttribute="trailing" constant="8" id="ndh-2g-JB9"/>
<constraint firstItem="jQs-eL-Df4" firstAttribute="width" secondItem="TuE-fA-Shh" secondAttribute="width" id="oPW-AK-dKc"/>
<constraint firstItem="yHB-42-ebc" firstAttribute="top" secondItem="VRq-kT-wkC" secondAttribute="bottom" constant="8" id="oeJ-JF-RKD"/>
<constraint firstItem="R5Q-JF-7P7" firstAttribute="width" secondItem="O9g-UA-3gp" secondAttribute="width" id="oxq-qE-PNY"/>
<constraint firstItem="5Ro-Ix-JD5" firstAttribute="firstBaseline" secondItem="Rz0-Kg-nHG" secondAttribute="firstBaseline" id="p1Y-oC-uPf"/>
<constraint firstItem="rxW-aA-Bai" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="p2O-K2-o1k"/>
<constraint firstItem="i6K-Iu-xdk" firstAttribute="leading" secondItem="qMp-14-9zW" secondAttribute="trailing" constant="8" id="pTv-cw-KOT"/>
<constraint firstItem="yHT-3q-ctP" firstAttribute="width" secondItem="WcI-SC-fZV" secondAttribute="width" id="py1-Eh-zaX"/>
<constraint firstItem="hLf-i4-NRV" firstAttribute="top" secondItem="ycZ-re-pMx" secondAttribute="bottom" constant="8" id="qXw-Lj-0TQ"/>
<constraint firstItem="dL6-2Y-CIz" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="qux-d1-Xew"/>
<constraint firstItem="WcI-SC-fZV" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="r1e-VI-uCi"/>
<constraint firstItem="GDm-WA-rkG" firstAttribute="top" secondItem="Fve-dp-udd" secondAttribute="bottom" constant="8" id="r8m-Lq-tOo"/>
<constraint firstItem="rxW-aA-Bai" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" id="sE3-LQ-suM"/>
<constraint firstItem="WCt-Ri-ndL" firstAttribute="top" secondItem="S5E-xU-QAK" secondAttribute="bottom" constant="8" id="sGu-iz-XWu"/>
<constraint firstItem="E3S-mU-OmJ" firstAttribute="leading" secondItem="RXV-hd-YH8" secondAttribute="trailing" constant="8" id="sJJ-wb-4ei"/>
<constraint firstItem="5wn-WM-n7f" firstAttribute="leading" secondItem="2BM-Lt-WwR" secondAttribute="trailing" constant="8" id="sri-x8-63C"/>
<constraint firstAttribute="trailing" secondItem="Ns3-zZ-EQY" secondAttribute="trailing" constant="20" id="tTK-hB-OcK"/>
<constraint firstItem="5DP-Qu-lS2" firstAttribute="width" secondItem="jQs-eL-Df4" secondAttribute="width" id="v4q-jw-tEN"/>
<constraint firstItem="vrB-v6-gvS" firstAttribute="width" secondItem="RXV-hd-YH8" secondAttribute="width" id="vOz-7q-3y1"/>
<constraint firstAttribute="trailing" secondItem="M0c-Sj-o1i" secondAttribute="trailing" constant="20" id="vSZ-0i-3xg"/>
<constraint firstItem="6dg-5z-gNX" firstAttribute="top" secondItem="56u-eS-Y7s" secondAttribute="bottom" constant="8" id="w60-xz-Iy3"/>
<constraint firstItem="iZL-4Q-g2k" firstAttribute="leading" secondItem="Ymc-Xn-VtU" secondAttribute="trailing" constant="8" id="wCh-Wh-Hlj"/>
<constraint firstItem="atg-Fg-IgS" firstAttribute="width" secondItem="NeB-Rh-CKs" secondAttribute="width" id="wHM-2M-Nn5"/>
<constraint firstItem="2BM-Lt-WwR" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="xDh-um-N7F"/>
<constraint firstItem="W7s-0d-JNo" firstAttribute="firstBaseline" secondItem="rsc-8R-cwh" secondAttribute="firstBaseline" id="xJA-hJ-9ju"/>
<constraint firstItem="HIj-cE-Twd" firstAttribute="top" secondItem="GDm-WA-rkG" secondAttribute="bottom" constant="8" id="y1B-3t-tX1"/>
<constraint firstItem="6dg-5z-gNX" firstAttribute="leading" secondItem="WcI-SC-fZV" secondAttribute="trailing" constant="8" id="yFh-hz-kHH"/>
<constraint firstItem="hfx-Lg-t9P" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="yfN-yW-OCy"/>
<constraint firstItem="Lw1-zP-Vdy" firstAttribute="top" secondItem="E3S-mU-OmJ" secondAttribute="bottom" constant="8" id="z2d-6U-MiE"/>
<constraint firstItem="0FY-cv-M9B" firstAttribute="top" secondItem="Ns3-zZ-EQY" secondAttribute="bottom" constant="8" id="z51-WK-EFf"/>
<constraint firstItem="fG8-lF-YYW" firstAttribute="width" secondItem="eyk-QN-lkH" secondAttribute="width" id="zN5-Ta-ZyL"/>
<constraint firstItem="AiU-u8-z9t" firstAttribute="width" secondItem="3Cb-Ht-JzJ" secondAttribute="width" id="zY2-nG-XLO"/>
</constraints>
<point key="canvasLocation" x="100.5" y="301.5"/>
</customView>
</objects>
</document>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>

25
macosx/Snes9x/main.m Normal file
View File

@ -0,0 +1,25 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#import <Cocoa/Cocoa.h>
int main(int argc, const char * argv[]) {
return NSApplicationMain(argc, argv);
}

View File

@ -1,68 +1,61 @@
{\rtf1\ansi\ansicpg932\cocoartf1038\cocoasubrtf350 {\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
{\fonttbl\f0\fnil\fcharset0 LucidaGrande;} \cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 LucidaGrande;\f1\fnil\fcharset0 LucidaGrande-Bold;}
{\colortbl;\red255\green255\blue255;\red153\green102\blue51;\red0\green0\blue255;} {\colortbl;\red255\green255\blue255;\red153\green102\blue51;\red0\green0\blue255;}
\paperw11900\paperh16840\margl1440\margr1440\vieww11500\viewh12340\viewkind0 {\*\expandedcolortbl;;\csgenericrgb\c60000\c40000\c20000;\csgenericrgb\c0\c0\c100000;}
\pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\ql\qnatural \paperw11905\paperh16837\margl1440\margr1440\vieww11500\viewh12340\viewkind0
\pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\partightenfactor0
\f0\fs24 \cf0 \ \f0\fs24 \cf0 \
\b\fs28 FAQ for Mac port \f1\b\fs28 FAQ for Mac port
\b0\fs24 \ \f0\b0\fs24 \
\ \
\ \
\pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\ql\qnatural \pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\partightenfactor0
\b\fs26 \cf2 Differences and similarities among the Mac port and other ports \f1\b\fs26 \cf2 Differences and similarities among the Mac port and other ports
\b0\fs24 \cf0 \ \f0\b0\fs24 \cf0 \
\
\pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\ql\qnatural
\cf3 Key mapping\cf0 \
The default settings of key mapping are different. For example, the A-button is the command key on Mac, while it's the D key in Windows.\
\ \
\pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\partightenfactor0
\cf3 User interface\cf0 \ \cf3 User interface\cf0 \
All of the menus and dialogs are different.\ All of the menus and dialogs are different.\
\ \
\cf3 AVI or QuickTime export\cf0 \
Mac port supports QuickTime export instead of AVI export in Windows port.\
\
\cf3 Sound effect and Core Image filter\cf0 \
These features are for Mac only because they use Mac OS X's own technologies.\
\
\cf3 Netplay\cf0 \
Snes9x's netplay is incompatible between ports.\
\
\cf3 Command-line options\cf0 \
Mac port doesn't support command-line options.\
\
\cf3 Preferences file\cf0 \ \cf3 Preferences file\cf0 \
Mac port doesn't support 'snes9x.conf' file.\ Mac port doesn't support 'snes9x.conf' file.\
\ \
\ \
\pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\ql\qnatural \pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\partightenfactor0
\b\fs26 \cf2 Emulator Specific Questions \f1\b\fs26 \cf2 Emulator Specific Questions
\b0\fs24 \cf0 \ \f0\b0\fs24 \cf0 \
\ \
\pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\ql\qnatural \pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\partightenfactor0
\cf3 Everything is fine when I play the game, but the next time I play, my save data is not there. Why?\cf0 \ \cf3 Everything is fine when I play the game, but the next time I play, my save data is not there. Why?\cf0 \
Saving files into a locked volume and folders where you don't have permission to write will fail. Make sure where you are saving files in 'Preferences' dialog. The most common case for Mac beginners is launching Snes9x directly from the disk image with choosing 'Snes9x folder' for saving destination.\ Saving files into a locked volume and folders where you don't have permission to write will fail. Make sure where you are saving files in 'Preferences' dialog. The most common case for Mac beginners is launching Snes9x directly from the disk image with choosing 'Snes9x folder' for saving destination.\
\ \
\cf3 Where did Cheats/Movie Recording/Netplay/most of the preferences go?\
\pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\partightenfactor0
\cf0 Snes9x is currently being ported from Carbon to Cocoa in order to work with macOS Catalina. Because this process is time-consuming, features are being added back over time. If there\'92s a specific feature you\'92d like to see return before others, please upvote an issue, or create one if none exists, at {\field{\*\fldinst{HYPERLINK "https://github.com/snes9xgit/snes9x/issues"}}{\fldrslt https://github.com/snes9xgit/snes9x/issues}}.\
\
\pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\partightenfactor0
\cf3 Why did my keyboard controls change when I upgraded?\
\pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\partightenfactor0
\cf0 The Cocoa port of Snes9x \
\
\pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\partightenfactor0
\cf3 Why can't I press many buttons at once? Especially in Chrono Trigger.\cf0 \ \cf3 Why can't I press many buttons at once? Especially in Chrono Trigger.\cf0 \
Some keyboards can only output two pressed keys at a time, except for modifier keys (shift, command, option and control). Set modifier keys to some of the necessary buttons.\ Some keyboards can only output two pressed keys at a time, except for modifier keys (shift, command, option and control). Set modifier keys to some of the necessary buttons.\
\ \
\cf3 How can I enter the Game Genie / PAR code in 'Cheat Entry' dialog?\cf0 \
Simply enter the code directly into the address column. Snes9x automatically translates it to the general format.\
\
\cf3 I recently purchased a gamepad controller. Will it work on Snes9x?\ \cf3 I recently purchased a gamepad controller. Will it work on Snes9x?\
\pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\ql\qnatural \pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\partightenfactor0
\cf0 If your gamepad is conformable to USB Device Class Definition for Human Interface Devices, it may work. Note that most gamepads don't officially support Mac OS X even if they work without problems.\cf3 \ \cf0 If your gamepad is conformable to USB Device Class Definition for Human Interface Devices, it may work. Note that most gamepads don't officially support Mac OS X even if they work without problems.\cf3 \
\ \
I connected my gamepad but it doesn't work.\cf0 \ I connected my gamepad but it doesn't work.\cf0 \
Gamepads cannot be used until you configure its settings in 'Configure Controllers' dialog.\ Gamepads cannot be used until you configure its settings in 'Configure Controllers' dialog.\
\ \
\pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\ql\qnatural \pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\partightenfactor0
\cf3 I think my options in Snes9x got screwed up, how do I reset them?\cf0 \ \cf3 I think my options in Snes9x got screwed up, how do I reset them?\cf0 \
Quit Snes9x and trash the preferences file 'com.snes9x.macos.snes9x.plist' in ~/Library/Preferences.\ Quit Snes9x and trash the preferences files 'com.snes9x.macos.snes9x.plist' in ~/Library/Preferences and in /Library/Preferences. You may need to reboot afterwords. Alternately, you can use the command \'91defaults delete com.snes9x.macos.snes9x\'92 in Terminal.app to avoid restarting.\
\ \
\cf3 I had a bad checksummed game that didn't work so I adjusted the header, but it still doesn't work :( Why?\cf0 \ \cf3 I had a bad checksummed game that didn't work so I adjusted the header, but it still doesn't work :( Why?\cf0 \
It should be noted that while it is possible to plop a ROM into Snestool, or several other programs, and adjust the header size to be the same as a proper 'good checksum' ROM, this merely mimics the appearance of a good ROM. Any problems still found within its evil will remain. One could compare it to covering up a circumorbital haematoma with a paper bag.\ It should be noted that while it is possible to plop a ROM into Snestool, or several other programs, and adjust the header size to be the same as a proper 'good checksum' ROM, this merely mimics the appearance of a good ROM. Any problems still found within its evil will remain. One could compare it to covering up a circumorbital haematoma with a paper bag.\
@ -74,12 +67,12 @@ I connected my gamepad but it doesn't work.\cf0 \
Chances are it will be coming out when enough changes have been made to suitably make a release. You can generally guesstimate the release date by paying attention to the Developers forum at snes9x.com. But don't ask them when the next release will be.\ Chances are it will be coming out when enough changes have been made to suitably make a release. You can generally guesstimate the release date by paying attention to the Developers forum at snes9x.com. But don't ask them when the next release will be.\
\ \
\ \
\pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\ql\qnatural \pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\partightenfactor0
\b\fs26 \cf2 Miscellaneous Questions \f1\b\fs26 \cf2 Miscellaneous Questions
\b0\fs24 \cf0 \ \f0\b0\fs24 \cf0 \
\ \
\pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\ql\qnatural \pard\tx285\tx1133\tx1700\tx2266\tx2832\tx3401\tx3967\tx4535\tx5102\tx5669\tx6235\tx6802\partightenfactor0
\cf3 Is it legal?\cf0 \ \cf3 Is it legal?\cf0 \
This has been asked time and again, and the answer is yes. Developing, downloading, or using the emulator, Snes9x, is completely legal. Downloading games, called ROMS, however is not. If you own the original cartridge of a game, you are still not entitled to download the ROM image of that game. You may create a single backup image of your own cartridge via proper hardware, but it must be YOUR cartridge and is only usable in place of the original... so only one may be active at any time. Many sites claim that you may legally download ROMs for up to 24 hours before they must be deleted. This is also wrong; you can't legally download these for "trial" purposes. You can't download ROMs for educational purposes either. If you wish to use Super Nintendo Entertainment System games for educational purposes, contact your closest Nintendo Outlet and discuss educational programming with them. Finally, a small number of ROMs are labeled "(PD)". This means public domain, and these games are not under copyright. As such they are legal to download at your hearts content. These include programs created by internet users such as yourself for use in Super Nintendo emulators. As of this time there are no commercial videogames in the public domain.\ This has been asked time and again, and the answer is yes. Developing, downloading, or using the emulator, Snes9x, is completely legal. Downloading games, called ROMS, however is not. If you own the original cartridge of a game, you are still not entitled to download the ROM image of that game. You may create a single backup image of your own cartridge via proper hardware, but it must be YOUR cartridge and is only usable in place of the original... so only one may be active at any time. Many sites claim that you may legally download ROMs for up to 24 hours before they must be deleted. This is also wrong; you can't legally download these for "trial" purposes. You can't download ROMs for educational purposes either. If you wish to use Super Nintendo Entertainment System games for educational purposes, contact your closest Nintendo Outlet and discuss educational programming with them. Finally, a small number of ROMs are labeled "(PD)". This means public domain, and these games are not under copyright. As such they are legal to download at your hearts content. These include programs created by internet users such as yourself for use in Super Nintendo emulators. As of this time there are no commercial videogames in the public domain.\
\ \

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 679 B

After

Width:  |  Height:  |  Size: 679 B

View File

@ -30,11 +30,10 @@
</ul> </ul>
<h4>As with all things there are disadvantages though :</h4> <h4>As with all things there are disadvantages though :</h4>
<ul> <ul>
<li>if you have an ancient computer, you aren't likely to get a playable experience.</li>
<li>some games are still unemulated (though this a very tiny minority.)</li> <li>some games are still unemulated (though this a very tiny minority.)</li>
<li>the emulator can be difficult for new users to configure.</li> <li>the emulator can be difficult for new users to configure.</li>
</ul> </ul>
<div style="text-align:center; margin-top:3em"><p> <div style="text-align:center; margin-top:3em"><p>
&lt;Prev&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;<a href="02.html">Next</a>&gt; &lt;Prev&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;<a href="02.html">Next</a>&gt;
</p></div> </p></div>
</body> </body>

View File

@ -13,7 +13,7 @@
<body> <body>
<h2>Getting Started</h2> <h2>Getting Started</h2>
<p> <p>
Copy the Snes9x application from the disk image (.dmg) to your hard disk and double-click it. Copy the Snes9x application to your hard Applications Folder and double-click it.
</p> </p>
<h3>Loading Games</h3> <h3>Loading Games</h3>
<p> <p>
@ -64,7 +64,7 @@
</p> </p>
<h3>SNES Joypad Emulation</h3> <h3>SNES Joypad Emulation</h3>
<p> <p>
The default key mapping for joypad 1 is as follows: The Mac port now uses the same default key mapping as the Windows port. The default key mapping for joypad 1 is as follows:
</p> </p>
<ul> <ul>
<li><table summary="default key mapping"> <li><table summary="default key mapping">
@ -86,35 +86,35 @@
<td>Right direction</td> <td>Right direction</td>
</tr> </tr>
<tr valign="top"> <tr valign="top">
<td style="width:9em">command</td> <td style="width:9em">V</td>
<td>A button</td> <td>A button</td>
</tr> </tr>
<tr valign="top"> <tr valign="top">
<td style="width:9em">option</td> <td style="width:9em">C</td>
<td>B button</td> <td>B button</td>
</tr> </tr>
<tr valign="top"> <tr valign="top">
<td style="width:9em">control</td> <td style="width:9em">D</td>
<td>X button</td> <td>X button</td>
</tr> </tr>
<tr valign="top"> <tr valign="top">
<td style="width:9em">shift</td> <td style="width:9em">X</td>
<td>Y button</td> <td>Y button</td>
</tr> </tr>
<tr valign="top"> <tr valign="top">
<td style="width:9em">Z</td> <td style="width:9em">A</td>
<td>L button</td> <td>L button</td>
</tr> </tr>
<tr valign="top"> <tr valign="top">
<td style="width:9em">X</td> <td style="width:9em">S</td>
<td>R button</td> <td>R button</td>
</tr> </tr>
<tr valign="top"> <tr valign="top">
<td style="width:9em">tab</td> <td style="width:9em">return</td>
<td>Select button</td> <td>Select button</td>
</tr> </tr>
<tr valign="top"> <tr valign="top">
<td style="width:9em">return</td> <td style="width:9em">space</td>
<td>Start button</td> <td>Start button</td>
</tr> </tr>
</tbody> </tbody>
@ -122,9 +122,9 @@
</ul> </ul>
<h3>Pausing and Resuming the Game</h3> <h3>Pausing and Resuming the Game</h3>
<p> <p>
To pause the game, press pause key (esc key by default), choose 'Pause' in 'Emulation' menu, or click the game screen in case you aren't playing the game that uses a mouse. Double-click the game window or choose 'Resume' in 'Emulation' menu to resume the game. To pause the game, press pause key (esc key by default) or choose 'Pause' in 'Emulation' menu. Choose 'Resume' in 'Emulation' menu to resume the game.
</p> </p>
<div style="text-align:center; margin-top:3em"><p> <div style="text-align:center; margin-top:3em"><p>
&lt;<a href="01.html">Prev</a>&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;<a href="03.html">Next</a>&gt; &lt;<a href="01.html">Prev</a>&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;<a href="03.html">Next</a>&gt;
</p></div> </p></div>
</body> </body>

View File

@ -11,20 +11,14 @@
<h2>Requirements</h2> <h2>Requirements</h2>
<h3>System Requirements</h3> <h3>System Requirements</h3>
<p> <p>
Mac OS X 10.3.9 or later<br> Mac OS X 10.12 or later<br>
QuickTime 7.0 or later<br>
PowerPC G3 300MHz or later<br>
G-Force/ATI Rage 128 or later
</p>
<p>
Certain games use added hardware which will require a faster Mac. The specs listed above is the minimum to use Snes9x in any playable form. It is recommended that you get a semi-modern Mac with a 800MHz PowerPC processor if you want good results. A 1GHz PowerPC or Intel Mac is recommended for those that want a near perfect experience.
</p> </p>
<h3>Software</h3> <h3>Software</h3>
<p> <p>
You will need access to SNES ROM images otherwise you will have nothing to run! Some home-brewed ROM images can be downloaded from <a href="http://www.zophar.com/">http://www.zophar.com/</a>.<br> You will need access to SNES ROM images otherwise you will have nothing to run! Some home-brewed ROM images can be downloaded from <a href="http://www.zophar.com/">http://www.zophar.com/</a>.<br>
Please note, it is illegal in most countries to have commercial ROM images without also owning the actual SNES ROM cartridges, and even then you may be liable under various EULAs. Please note, it is illegal in most countries to have commercial ROM images without also owning the actual SNES ROM cartridges, and even then you may be liable under various EULAs.
</p> </p>
<div style="text-align:center; margin-top:3em"><p> <div style="text-align:center; margin-top:3em"><p>
&lt;<a href="02.html">Prev</a>&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;<a href="04.html">Next</a>&gt; &lt;<a href="02.html">Prev</a>&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;<a href="04.html">Next</a>&gt;
</p></div> </p></div>
</body> </body>

View File

@ -50,20 +50,8 @@
</p> </p>
<h3>Automatic Fire</h3> <h3>Automatic Fire</h3>
<p> <p>
The 'Automatic Fire...' dialog in the 'Config' menu provides five configuration options for simulating autofire controllers: Pressing Snes9x's Alt key in conjunction with that controller button in-game will toggle that button's 'Enable Automatic Fire' setting. Other autofire settings will return in future versions. If you use these settings, please upvote an existing issue or file a new issue at <a href="https://github.com/snes9xgit/snes9x/issues">https://github.com/snes9xgit/snes9x/issues</a> so we know which features to prioritize.
</p> </p>
<dl>
<dt>Enable Automatic Fire</dt>
<dd>If this option is enabled for a given controller button, holding down that button will produce a rapid-fire effect (barring the use of the 'Automatic Fire is Active Only While TC is Pressed' option - see below).</dd>
<dt>Allow Alt to Toggle Enable/Disable Automatic Fire</dt>
<dd>If this option is enabled for a given controller button, pressing Snes9x's Alt key in conjunction with that controller button in-game will toggle that button's 'Enable Automatic Fire' setting.</dd>
<dt>Automatic Fire is Active Only While TC is Pressed</dt>
<dd>If this option is enabled for a given controller button, you must hold down Snes9x's TC key in conjunction with that controller button in-game to produce a rapid-fire effect, provided that 'Enable Automatic Fire' is toggled on for that controller button. If TC is not depressed, that controller button will function as normal. Note that when 'Enable Automatic Fire' is toggled off for a controller button, its 'Automatic Fire is Active Only While TC is Pressed' setting has no effect.</dd>
<dt>Button Input is Inverted</dt>
<dd>If this option is enabled for a given controller button, Snes9x behaves as though you are pushing that controller button if and only if you are not pushing it. This option is most often used in conjunction with 'Enable Automatic Fire', producing a rapidly-firing controller button without any player intervention.</dd>
<dt>Automatic Fire Speed</dt>
<dd>This option controls the rate at which autofire controller buttons cycle their fire.</dd>
</dl>
<p> <p>
Snes9x's Alt and TC buttons can be mapped to both keyboard keys and joypad buttons, in the 'Configure Keyboard...' and 'Configure Controllers...' dialogs respectively. Snes9x's Alt and TC buttons can be mapped to both keyboard keys and joypad buttons, in the 'Configure Keyboard...' and 'Configure Controllers...' dialogs respectively.
</p> </p>
@ -197,7 +185,7 @@
</tbody> </tbody>
</table></li> </table></li>
</ul> </ul>
<div style="text-align:center; margin-top:3em"><p> <div style="text-align:center; margin-top:3em"><p>
&lt;<a href="03.html">Prev</a>&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;<a href="05.html">Next</a>&gt; &lt;<a href="03.html">Prev</a>&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;<a href="05.html">Next</a>&gt;
</p></div> </p></div>
</body> </body>

View File

@ -9,6 +9,7 @@
</head> </head>
<body> <body>
<h2>Cheat Support</h2> <h2>Cheat Support</h2>
<p><b>Cheat support will return in a future version. If you want to see it return faster, please upvote an existing issue or file a new issue at <a href="https://github.com/snes9xgit/snes9x/issues">https://github.com/snes9xgit/snes9x/issues</a> so we know which features to prioritize.</b></p>
<p> <p>
Cheat codes allow you to cheat at games. They might give you more lives, infinite health, enable special powers normally only activated when a special item is found, and etc. Two major formats are well-known: Game Genie and Pro-Action Reply (PAR). Many existing Game Genie and PAR codes can be found via Internet. Cheat codes allow you to cheat at games. They might give you more lives, infinite health, enable special powers normally only activated when a special item is found, and etc. Two major formats are well-known: Game Genie and Pro-Action Reply (PAR). Many existing Game Genie and PAR codes can be found via Internet.
</p> </p>
@ -52,7 +53,7 @@
<p> <p>
Now you'll find that the number of lives is 5 and the value doesn't decrease even you crash into an enemy. Snes9x keeps the value constant, so even if you do lose a life and life counter goes down by one, less than 20ms later, Snes9x resets the counter back to the value you chose! Now you'll find that the number of lives is 5 and the value doesn't decrease even you crash into an enemy. Snes9x keeps the value constant, so even if you do lose a life and life counter goes down by one, less than 20ms later, Snes9x resets the counter back to the value you chose!
</p> </p>
<div style="text-align:center; margin-top:3em"><p> <div style="text-align:center; margin-top:3em"><p>
&lt;<a href="06.html">Prev</a>&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;<a href="08.html">Next</a>&gt; &lt;<a href="06.html">Prev</a>&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;<a href="08.html">Next</a>&gt;
</p></div> </p></div>
</body> </body>

View File

@ -9,6 +9,7 @@
</head> </head>
<body> <body>
<h2>Movie Support</h2> <h2>Movie Support</h2>
<p><b>Movie support will return in a future version. If you want to see it return faster, please upvote an existing issue or file a new issue at <a href="https://github.com/snes9xgit/snes9x/issues">https://github.com/snes9xgit/snes9x/issues</a> so we know which features to prioritize.</b></p>
<p> <p>
Movie support allows you to record your actions while playing a game. This can be used for your own personal playback or to show other people that you can do something without them having to be around when you did it. Movie support allows you to record your actions while playing a game. This can be used for your own personal playback or to show other people that you can do something without them having to be around when you did it.
</p> </p>
@ -33,7 +34,7 @@
Choose 'Export to QuickTime Movie...' in 'Option' menu and choose the location where the QuickTime movie file will be saved. Press 'Compression...' button and set the compression settings by the general QuickTime dialog. 'Double Size' check box makes the movie size from 256x224/239 to 512x448/478. 'Overscan' check box is for games that use 239 or 478 lines. 'Frame Skip' menu decides frame rate of the movie, for example when the value is 1, NTSC games which have 60 fps are exported as 30 fps movie.<br> Choose 'Export to QuickTime Movie...' in 'Option' menu and choose the location where the QuickTime movie file will be saved. Press 'Compression...' button and set the compression settings by the general QuickTime dialog. 'Double Size' check box makes the movie size from 256x224/239 to 512x448/478. 'Overscan' check box is for games that use 239 or 478 lines. 'Frame Skip' menu decides frame rate of the movie, for example when the value is 1, NTSC games which have 60 fps are exported as 30 fps movie.<br>
To make a QuickTime movie from .smv, choose 'Play Movie...' in 'Option' menu and turn on 'Export to QuickTime movie at a Time' check box. To make a QuickTime movie from .smv, choose 'Play Movie...' in 'Option' menu and turn on 'Export to QuickTime movie at a Time' check box.
</p> </p>
<div style="text-align:center; margin-top:3em"><p> <div style="text-align:center; margin-top:3em"><p>
&lt;<a href="07.html">Prev</a>&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;<a href="09.html">Next</a>&gt; &lt;<a href="07.html">Prev</a>&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;<a href="09.html">Next</a>&gt;
</p></div> </p></div>
</body> </body>

View File

@ -12,6 +12,7 @@
</head> </head>
<body> <body>
<h2>Netplay Support</h2> <h2>Netplay Support</h2>
<p><b>Netplay does not currently work, and may not return in a future version. If you want to see it return, please upvote an existing issue or file a new issue at <a href="https://github.com/snes9xgit/snes9x/issues">https://github.com/snes9xgit/snes9x/issues</a> so we know that players are using it.</b></p>
<p> <p>
Netplay support allows up to five players to sit in front of different computers and simultaneously play the same game, or just watch someone else play a game. All the computers have to be connected to a network that allows TCP/IP traffic to flow between them; this includes a local Ethernet-style network, a direct-cable connection, or, if you're lucky and have short ping times, the Internet. Netplay support allows up to five players to sit in front of different computers and simultaneously play the same game, or just watch someone else play a game. All the computers have to be connected to a network that allows TCP/IP traffic to flow between them; this includes a local Ethernet-style network, a direct-cable connection, or, if you're lucky and have short ping times, the Internet.
</p> </p>
@ -97,7 +98,7 @@
</tbody> </tbody>
</table></li> </table></li>
</ul> </ul>
<div style="text-align:center; margin-top:3em"><p> <div style="text-align:center; margin-top:3em"><p>
&lt;<a href="08.html">Prev</a>&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;<a href="10.html">Next</a>&gt; &lt;<a href="08.html">Prev</a>&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;<a href="10.html">Next</a>&gt;
</p></div> </p></div>
</body> </body>

View File

@ -0,0 +1,23 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en-US">
<head>
<meta http-equiv="content-type" content="text/html;charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<meta name="description" content="References">
<link href="../sty/style.css" rel="stylesheet">
<title>References</title>
</head>
<body>
<h2>Preferences</h2>
<p><b>Many preferences have not yet been ported to the Cocoa version of Snes9x. If there is a preference you want to see added, please upvote an existing issue if it exists, or create a new one of no issue exists, at <a href="https://github.com/snes9xgit/snes9x/issues">https://github.com/snes9xgit/snes9x/issues</a>.</b></p>
<dl>
<dt>Video Mode</dt>
<dd>Choose the image scaling filter which is applied to the raw SNES image.</dd>
<dt>Show Frame Rate</dt>
<dd>Toggles display of the frame rate on/off.</dd>
</dl>
<div style="text-align:center; margin-top:3em"><p>
&lt;<a href="13.html">Prev</a>&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;<a href="15.html">Next</a>&gt;
</p></div>
</body>
</html>

View File

@ -60,9 +60,9 @@
</p></div> </p></div>
<p> <p>
Edited for Mac port by: zones (kasumitokoduck@yahoo.com)<br> Edited for Mac port by: zones (kasumitokoduck@yahoo.com)<br>
Updated most recently by: 2011/3/31 zones Updated most recently by: 2019/11/03 Michael Donald Buckley
</p> </p>
<div style="text-align:center; margin-top:3em"><p> <div style="text-align:center; margin-top:3em"><p>
&lt;<a href="14.html">Prev</a>&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;Next&gt; &lt;<a href="14.html">Prev</a>&nbsp;&nbsp;<a href="../index.html">Top</a>&nbsp;&nbsp;Next&gt;
</p></div> </p></div>
</body> </body>

View File

@ -0,0 +1,297 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MusicBoxController">
<connections>
<outlet property="disclosure" destination="62" id="93"/>
<outlet property="gametitle" destination="72" id="113"/>
<outlet property="indicator" destination="1" id="114"/>
<outlet property="led" destination="64" id="115"/>
<outlet property="rewind" destination="68" id="95"/>
<outlet property="window" destination="2" id="116"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Music Box" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="2">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="100" y="100" width="352" height="242"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="878"/>
<value key="minSize" type="size" width="352" height="61"/>
<value key="maxSize" type="size" width="352" height="242"/>
<view key="contentView" id="3">
<rect key="frame" x="0.0" y="0.0" width="352" height="242"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView id="120">
<rect key="frame" x="30" y="37" width="262" height="142"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" image="musicbox_indicator" id="121"/>
</imageView>
<button verticalHuggingPriority="750" imageHugsTitle="YES" id="6">
<rect key="frame" x="302" y="158" width="30" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" image="musicbox_pause" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="7">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handlePauseButton:" target="-2" id="123"/>
</connections>
</button>
<button verticalHuggingPriority="750" imageHugsTitle="YES" id="68">
<rect key="frame" x="302" y="134" width="30" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" image="musicbox_rewind" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="69">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleRewindButton:" target="-2" id="124"/>
</connections>
</button>
<button verticalHuggingPriority="750" imageHugsTitle="YES" id="70">
<rect key="frame" x="302" y="110" width="30" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" image="musicbox_effect" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="71">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleEffectButton:" target="-2" id="125"/>
</connections>
</button>
<customView id="1" customClass="MusicBoxIndicatorView">
<rect key="frame" x="36" y="43" width="250" height="130"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</customView>
<button verticalHuggingPriority="750" imageHugsTitle="YES" id="14">
<rect key="frame" x="41" y="19" width="12" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="15">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleChannelButton:" target="-2" id="127"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="5" imageHugsTitle="YES" id="26">
<rect key="frame" x="111" y="19" width="12" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="27">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleChannelButton:" target="-2" id="133"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="1" imageHugsTitle="YES" id="28">
<rect key="frame" x="55" y="19" width="12" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="29">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleChannelButton:" target="-2" id="129"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="2" imageHugsTitle="YES" id="30">
<rect key="frame" x="69" y="19" width="12" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="31">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleChannelButton:" target="-2" id="130"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="3" imageHugsTitle="YES" id="32">
<rect key="frame" x="83" y="19" width="12" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="33">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleChannelButton:" target="-2" id="131"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="4" imageHugsTitle="YES" id="34">
<rect key="frame" x="97" y="19" width="12" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="35">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleChannelButton:" target="-2" id="132"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="7" imageHugsTitle="YES" id="36">
<rect key="frame" x="139" y="19" width="12" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="37">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleChannelButton:" target="-2" id="135"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="6" imageHugsTitle="YES" id="38">
<rect key="frame" x="125" y="19" width="12" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="39">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleChannelButton:" target="-2" id="134"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="8" imageHugsTitle="YES" id="40">
<rect key="frame" x="171" y="19" width="12" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="55">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleChannelButton:" target="-2" id="136"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="13" imageHugsTitle="YES" id="41">
<rect key="frame" x="241" y="19" width="12" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="54">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleChannelButton:" target="-2" id="141"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="9" imageHugsTitle="YES" id="42">
<rect key="frame" x="185" y="19" width="12" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="53">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleChannelButton:" target="-2" id="137"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="10" imageHugsTitle="YES" id="43">
<rect key="frame" x="199" y="19" width="12" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="52">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleChannelButton:" target="-2" id="138"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="11" imageHugsTitle="YES" id="44">
<rect key="frame" x="213" y="19" width="12" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="51">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleChannelButton:" target="-2" id="139"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="12" imageHugsTitle="YES" id="45">
<rect key="frame" x="227" y="19" width="12" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="50">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleChannelButton:" target="-2" id="140"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="15" imageHugsTitle="YES" id="46">
<rect key="frame" x="269" y="19" width="12" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="49">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleChannelButton:" target="-2" id="143"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="14" imageHugsTitle="YES" id="47">
<rect key="frame" x="255" y="19" width="12" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="48">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleChannelButton:" target="-2" id="142"/>
</connections>
</button>
<button horizontalHuggingPriority="750" verticalHuggingPriority="750" imageHugsTitle="YES" id="62">
<rect key="frame" x="307" y="198" width="29" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="disclosure" bezelStyle="roundedDisclosure" imagePosition="only" alignment="center" state="on" borderStyle="border" inset="2" id="63">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="handleDisclosureButton:" target="-2" id="126"/>
</connections>
</button>
<imageView id="64">
<rect key="frame" x="153" y="18" width="16" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="musicbox_ledoff" id="65"/>
</imageView>
<textField verticalHuggingPriority="750" id="66">
<rect key="frame" x="17" y="203" width="58" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Playing :" bezelStyle="round" id="67">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" id="72">
<rect key="frame" x="77" y="203" width="218" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Game Title" bezelStyle="round" id="73">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="-2" id="146"/>
</connections>
</window>
</objects>
<resources>
<image name="musicbox_effect" width="16" height="16"/>
<image name="musicbox_indicator" width="262" height="142"/>
<image name="musicbox_ledoff" width="16" height="16"/>
<image name="musicbox_pause" width="16" height="16"/>
<image name="musicbox_rewind" width="16" height="16"/>
</resources>
</document>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -1,167 +0,0 @@
/*****************************************************************************\
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 "port.h"
#include "mac-prefix.h"
#include "mac-os.h"
#include "mac-snes9x.h"
#include "mac-appleevent.h"
static AEEventHandlerUPP oappUPP, rappUPP, pdocUPP, quitUPP, odocUPP;
static pascal OSErr AEoapp (const AppleEvent *, AppleEvent *, long);
static pascal OSErr AErapp (const AppleEvent *, AppleEvent *, long);
static pascal OSErr AEpdoc (const AppleEvent *, AppleEvent *, long);
static pascal OSErr AEquit (const AppleEvent *, AppleEvent *, long);
static pascal OSErr AEodoc (const AppleEvent *, AppleEvent *, long);
static pascal OSErr AEoapp (const AppleEvent *theEvent, AppleEvent *theReply, long refCon)
{
if (running)
return (noErr);
if (startopendlog)
{
if (SNES9X_OpenCart(NULL))
{
SNES9X_Go();
QuitApplicationEventLoop();
}
else
AdjustMenus();
}
return (noErr);
}
static pascal OSErr AErapp (const AppleEvent *theEvent, AppleEvent *theReply, long refCon)
{
if (running)
return (noErr);
if (!cartOpen)
{
if (startopendlog)
{
if (SNES9X_OpenCart(NULL))
{
SNES9X_Go();
QuitApplicationEventLoop();
}
else
AdjustMenus();
}
}
else
{
SNES9X_Go();
QuitApplicationEventLoop();
}
return (noErr);
}
static pascal OSErr AEpdoc (const AppleEvent *theEvent, AppleEvent *theReply, long refCon)
{
return (errAEEventNotHandled);
}
static pascal OSErr AEquit (const AppleEvent *theEvent, AppleEvent *theReply, long refCon)
{
if (running)
return (noErr);
SNES9X_Quit();
QuitApplicationEventLoop();
return (noErr);
}
static pascal OSErr AEodoc (const AppleEvent *theEvent, AppleEvent *theReply, long refCon)
{
OSErr err;
FSRef ref;
AEDescList docList;
AEKeyword keywd;
DescType rtype;
Size acsize;
long count;
if (running)
return (noErr);
err = AEGetParamDesc(theEvent, keyDirectObject, typeAEList, &docList);
if (err)
return (noErr);
err = AECountItems(&docList, &count);
if (err || (count != 1))
{
err = AEDisposeDesc(&docList);
return (noErr);
}
err = AEGetNthPtr(&docList, 1, typeFSRef, &keywd, &rtype, &ref, sizeof(FSRef), &acsize);
if (err == noErr)
{
if (SNES9X_OpenCart(&ref))
{
SNES9X_Go();
QuitApplicationEventLoop();
}
else
AdjustMenus();
}
err = AEDisposeDesc(&docList);
return (noErr);
}
void InitAppleEvents (void)
{
OSErr err;
oappUPP = NewAEEventHandlerUPP(AEoapp);
err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, oappUPP, 0L, false);
odocUPP = NewAEEventHandlerUPP(AEodoc);
err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, odocUPP, 0L, false);
pdocUPP = NewAEEventHandlerUPP(AEpdoc);
err = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, pdocUPP, 0L, false);
quitUPP = NewAEEventHandlerUPP(AEquit);
err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, quitUPP, 0L, false);
rappUPP = NewAEEventHandlerUPP(AErapp);
err = AEInstallEventHandler(kCoreEventClass, kAEReopenApplication, rappUPP, 0L, false);
}
void DeinitAppleEvents (void)
{
DisposeAEEventHandlerUPP(oappUPP);
DisposeAEEventHandlerUPP(odocUPP);
DisposeAEEventHandlerUPP(pdocUPP);
DisposeAEEventHandlerUPP(quitUPP);
DisposeAEEventHandlerUPP(rappUPP);
}

View File

@ -15,6 +15,7 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/

169
macosx/mac-appleevent.mm Executable file
View File

@ -0,0 +1,169 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#include "port.h"
#include "mac-prefix.h"
#include "mac-os.h"
#include "mac-snes9x.h"
#include "mac-appleevent.h"
static AEEventHandlerUPP oappUPP, rappUPP, pdocUPP, quitUPP, odocUPP;
static OSErr AEoapp (const AppleEvent *, AppleEvent *, long);
static OSErr AErapp (const AppleEvent *, AppleEvent *, long);
static OSErr AEpdoc (const AppleEvent *, AppleEvent *, long);
static OSErr AEquit (const AppleEvent *, AppleEvent *, long);
static OSErr AEodoc (const AppleEvent *, AppleEvent *, long);
static OSErr AEoapp (const AppleEvent *theEvent, AppleEvent *theReply, long refCon)
{
if (running)
return (noErr);
if (startopendlog)
{
if (SNES9X_OpenCart(NULL))
{
SNES9X_Go();
//QuitApplicationEventLoop();
}
else
AdjustMenus();
}
return (noErr);
}
static OSErr AErapp (const AppleEvent *theEvent, AppleEvent *theReply, long refCon)
{
if (running)
return (noErr);
if (!cartOpen)
{
if (startopendlog)
{
if (SNES9X_OpenCart(NULL))
{
SNES9X_Go();
//QuitApplicationEventLoop();
}
else
AdjustMenus();
}
}
else
{
SNES9X_Go();
//QuitApplicationEventLoop();
}
return (noErr);
}
static OSErr AEpdoc (const AppleEvent *theEvent, AppleEvent *theReply, long refCon)
{
return (errAEEventNotHandled);
}
static OSErr AEquit (const AppleEvent *theEvent, AppleEvent *theReply, long refCon)
{
if (running)
return (noErr);
SNES9X_Quit();
//QuitApplicationEventLoop();
return (noErr);
}
static OSErr AEodoc (const AppleEvent *theEvent, AppleEvent *theReply, long refCon)
{
// OSErr err;
// FSRef ref;
// AEDescList docList;
// AEKeyword keywd;
// DescType rtype;
// Size acsize;
// long count;
//
// if (running)
// return (noErr);
//
// err = AEGetParamDesc(theEvent, keyDirectObject, typeAEList, &docList);
// if (err)
// return (noErr);
//
// err = AECountItems(&docList, &count);
// if (err || (count != 1))
// {
// err = AEDisposeDesc(&docList);
// return (noErr);
// }
//
// err = AEGetNthPtr(&docList, 1, typeFSRef, &keywd, &rtype, &ref, sizeof(FSRef), &acsize);
// if (err == noErr)
// {
// if (SNES9X_OpenCart(&ref))
// {
// SNES9X_Go();
// //QuitApplicationEventLoop();
// }
// else
// AdjustMenus();
// }
//
// err = AEDisposeDesc(&docList);
//
// return (noErr);
return 0;
}
void InitAppleEvents (void)
{
// OSErr err;
//
// oappUPP = NewAEEventHandlerUPP(AEoapp);
// err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, oappUPP, 0L, false);
//
// odocUPP = NewAEEventHandlerUPP(AEodoc);
// err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, odocUPP, 0L, false);
//
// pdocUPP = NewAEEventHandlerUPP(AEpdoc);
// err = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, pdocUPP, 0L, false);
//
// quitUPP = NewAEEventHandlerUPP(AEquit);
// err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, quitUPP, 0L, false);
//
// rappUPP = NewAEEventHandlerUPP(AErapp);
// err = AEInstallEventHandler(kCoreEventClass, kAEReopenApplication, rappUPP, 0L, false);
}
void DeinitAppleEvents (void)
{
DisposeAEEventHandlerUPP(oappUPP);
DisposeAEEventHandlerUPP(odocUPP);
DisposeAEEventHandlerUPP(pdocUPP);
DisposeAEEventHandlerUPP(quitUPP);
DisposeAEEventHandlerUPP(rappUPP);
}

View File

@ -15,6 +15,7 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/
@ -28,6 +29,5 @@ void DeinitMacSound (void);
void MacStartSound (void); void MacStartSound (void);
void MacStopSound (void); void MacStopSound (void);
void ConfigureSoundEffects (void); void ConfigureSoundEffects (void);
void PlayAlertSound (void);
#endif #endif

View File

@ -15,6 +15,7 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/
@ -43,11 +44,6 @@ int cureffect = kAUReverb;
static AUGraph agraph; static AUGraph agraph;
static AUNode outNode, cnvNode, revNode, eqlNode; static AUNode outNode, cnvNode, revNode, eqlNode;
static AudioUnit outAU, cnvAU, revAU, eqlAU; static AudioUnit outAU, cnvAU, revAU, eqlAU;
static AudioUnitCarbonView carbonView = NULL;
static EventHandlerUPP carbonViewEventUPP = NULL;
static EventHandlerRef carbonViewEventRef = NULL;
static WindowRef effectWRef;
static HISize effectWSize;
static pthread_mutex_t mutex; static pthread_mutex_t mutex;
static UInt32 outStoredFrames, cnvStoredFrames, revStoredFrames, eqlStoredFrames, devStoredFrames; static UInt32 outStoredFrames, cnvStoredFrames, revStoredFrames, eqlStoredFrames, devStoredFrames;
static int16_t *audioBuffer; static int16_t *audioBuffer;
@ -63,12 +59,8 @@ static void SetAudioUnitSoundFormat (void);
static void SetAudioUnitVolume (void); static void SetAudioUnitVolume (void);
static void StoreBufferFrameSize (void); static void StoreBufferFrameSize (void);
static void ChangeBufferFrameSize (void); static void ChangeBufferFrameSize (void);
static void ReplaceAudioUnitCarbonView (void);
static void ResizeSoundEffectsDialog (HIViewRef);
static void MacSamplesAvailableCallBack (void *); static void MacSamplesAvailableCallBack (void *);
static OSStatus MacAURenderCallBack (void *, AudioUnitRenderActionFlags *, const AudioTimeStamp *, UInt32, UInt32, AudioBufferList *); static OSStatus MacAURenderCallBack (void *, AudioUnitRenderActionFlags *, const AudioTimeStamp *, UInt32, UInt32, AudioBufferList *);
static pascal OSStatus SoundEffectsEventHandler (EventHandlerCallRef, EventRef, void *);
static pascal OSStatus SoundEffectsCarbonViewEventHandler (EventHandlerCallRef, EventRef, void *);
void InitMacSound (void) void InitMacSound (void)
@ -77,11 +69,7 @@ void InitMacSound (void)
err = NewAUGraph(&agraph); err = NewAUGraph(&agraph);
#ifndef MAC_LEOPARD_TIGER_PANTHER_SUPPORT
AudioComponentDescription outdesc, cnvdesc, revdesc, eqldesc; AudioComponentDescription outdesc, cnvdesc, revdesc, eqldesc;
#else
ComponentDescription outdesc, cnvdesc, revdesc, eqldesc;
#endif
outdesc.componentType = kAudioUnitType_Output; outdesc.componentType = kAudioUnitType_Output;
outdesc.componentSubType = kAudioUnitSubType_DefaultOutput; outdesc.componentSubType = kAudioUnitSubType_DefaultOutput;
@ -107,31 +95,18 @@ void InitMacSound (void)
eqldesc.componentFlags = 0; eqldesc.componentFlags = 0;
eqldesc.componentFlagsMask = 0; eqldesc.componentFlagsMask = 0;
#ifndef MAC_LEOPARD_TIGER_PANTHER_SUPPORT
err = AUGraphAddNode(agraph, &outdesc, &outNode); err = AUGraphAddNode(agraph, &outdesc, &outNode);
err = AUGraphAddNode(agraph, &cnvdesc, &cnvNode); err = AUGraphAddNode(agraph, &cnvdesc, &cnvNode);
err = AUGraphAddNode(agraph, &revdesc, &revNode); err = AUGraphAddNode(agraph, &revdesc, &revNode);
err = AUGraphAddNode(agraph, &eqldesc, &eqlNode); err = AUGraphAddNode(agraph, &eqldesc, &eqlNode);
#else
err = AUGraphNewNode(agraph, &outdesc, 0, NULL, &outNode);
err = AUGraphNewNode(agraph, &cnvdesc, 0, NULL, &cnvNode);
err = AUGraphNewNode(agraph, &revdesc, 0, NULL, &revNode);
err = AUGraphNewNode(agraph, &eqldesc, 0, NULL, &eqlNode);
#endif
err = AUGraphOpen(agraph); err = AUGraphOpen(agraph);
#ifndef MAC_LEOPARD_TIGER_PANTHER_SUPPORT
err = AUGraphNodeInfo(agraph, outNode, NULL, &outAU); err = AUGraphNodeInfo(agraph, outNode, NULL, &outAU);
err = AUGraphNodeInfo(agraph, cnvNode, NULL, &cnvAU); err = AUGraphNodeInfo(agraph, cnvNode, NULL, &cnvAU);
err = AUGraphNodeInfo(agraph, revNode, NULL, &revAU); err = AUGraphNodeInfo(agraph, revNode, NULL, &revAU);
err = AUGraphNodeInfo(agraph, eqlNode, NULL, &eqlAU); err = AUGraphNodeInfo(agraph, eqlNode, NULL, &eqlAU);
#else
err = AUGraphGetNodeInfo(agraph, outNode, NULL, NULL, NULL, &outAU);
err = AUGraphGetNodeInfo(agraph, cnvNode, NULL, NULL, NULL, &cnvAU);
err = AUGraphGetNodeInfo(agraph, revNode, NULL, NULL, NULL, &revAU);
err = AUGraphGetNodeInfo(agraph, eqlNode, NULL, NULL, NULL, &eqlAU);
#endif
SetAudioUnitSoundFormat(); SetAudioUnitSoundFormat();
SetAudioUnitVolume(); SetAudioUnitVolume();
@ -291,12 +266,7 @@ static void ConnectAudioUnits (void)
callback.inputProc = MacAURenderCallBack; callback.inputProc = MacAURenderCallBack;
callback.inputProcRefCon = NULL; callback.inputProcRefCon = NULL;
if (systemVersion >= 0x1050) err = AUGraphSetNodeInputCallback(agraph, aueffect ? cnvNode : outNode, 0, &callback);
err = AUGraphSetNodeInputCallback(agraph, aueffect ? cnvNode : outNode, 0, &callback);
#ifdef MAC_TIGER_PANTHER_SUPPORT
else
err = AudioUnitSetProperty(aueffect ? cnvAU : outAU, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &callback, sizeof(callback));
#endif
if ((aueffect & kAUReverb) && (aueffect & kAUGraphEQ)) if ((aueffect & kAUReverb) && (aueffect & kAUGraphEQ))
{ {
@ -510,445 +480,157 @@ bool8 S9xOpenSoundDevice (void)
return (true); return (true);
} }
void PlayAlertSound (void)
{
if (systemVersion >= 0x1050)
AudioServicesPlayAlertSound(kUserPreferredAlert);
#ifdef MAC_TIGER_PANTHER_SUPPORT
else
SysBeep(10);
#endif
}
static void ReplaceAudioUnitCarbonView (void)
{
OSStatus err;
AudioUnit editau;
Component cmp;
ComponentDescription desc;
HIViewRef pane, contentview, ctl;
HIViewID cid;
Float32Point location, size;
Rect rct;
UInt32 psize;
if (carbonView)
{
err = RemoveEventHandler(carbonViewEventRef);
DisposeEventHandlerUPP(carbonViewEventUPP);
carbonViewEventRef = NULL;
carbonViewEventUPP = NULL;
CloseComponent(carbonView);
carbonView = NULL;
}
switch (cureffect)
{
case kAUGraphEQ:
editau = eqlAU;
break;
case kAUReverb:
default:
editau = revAU;
break;
}
desc.componentType = kAudioUnitCarbonViewComponentType;
desc.componentSubType = kAUCarbonViewSubType_Generic;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
err = AudioUnitGetPropertyInfo(editau, kAudioUnitProperty_GetUIComponentList, kAudioUnitScope_Global, 0, &psize, NULL);
if (err == noErr)
{
ComponentDescription *editors;
int nEditors;
nEditors = psize / sizeof(ComponentDescription);
editors = new ComponentDescription[nEditors];
err = AudioUnitGetProperty(editau, kAudioUnitProperty_GetUIComponentList, kAudioUnitScope_Global, 0, editors, &psize);
if (err == noErr)
desc = editors[0];
delete [] editors;
}
HIViewFindByID(HIViewGetRoot(effectWRef), kHIViewWindowContentID, &contentview);
cmp = FindNextComponent(NULL, &desc);
if (cmp)
{
err = OpenAComponent(cmp, &carbonView);
if (err == noErr)
{
EventTypeSpec event[] = { { kEventClassControl, kEventControlBoundsChanged } };
GetWindowBounds(effectWRef, kWindowContentRgn, &rct);
location.x = 20;
location.y = 96;
size.x = rct.right - rct.left;
size.y = rct.bottom - rct.top;
err = AudioUnitCarbonViewCreate(carbonView, editau, effectWRef, contentview, &location, &size, &pane);
carbonViewEventUPP = NewEventHandlerUPP(SoundEffectsCarbonViewEventHandler);
err = InstallControlEventHandler(pane, carbonViewEventUPP, GetEventTypeCount(event), event, (void *) effectWRef, &carbonViewEventRef);
ResizeSoundEffectsDialog(pane);
}
else
carbonView = NULL;
}
else
carbonView = NULL;
cid.id = 0;
cid.signature = 'Enab';
HIViewFindByID(contentview, cid, &ctl);
SetControl32BitValue(ctl, (aueffect & cureffect) ? 1 : 0);
}
static void ResizeSoundEffectsDialog (HIViewRef view)
{
OSStatus err;
HIViewRef ctl, root;
HIViewID cid;
HIRect bounds;
Rect rv;
int w, h;
root = HIViewGetRoot(effectWRef);
cid.id = 0;
cid.signature = 'Enab';
HIViewFindByID(root, cid, &ctl);
err = HIViewSetVisible(ctl, false);
err = HIViewSetVisible(view, false);
HIViewGetBounds(view, &bounds);
w = ((int) bounds.size.width + 30 > (int) effectWSize.width) ? ((int) bounds.size.width + 30) : (int) effectWSize.width;
h = (int) bounds.size.height + 122;
#ifdef MAC_PANTHER_SUPPORT
if (systemVersion < 0x1040)
h += 16;
#endif
GetWindowBounds(effectWRef, kWindowStructureRgn, &rv);
rv.right = rv.left + w;
rv.bottom = rv.top + h;
err = TransitionWindow(effectWRef, kWindowSlideTransitionEffect, kWindowResizeTransitionAction, &rv);
err = HIViewSetVisible(ctl, true);
err = HIViewSetVisible(view, true);
#ifdef MAC_PANTHER_SUPPORT
if (systemVersion < 0x1040)
{
HIRect frame;
Rect rct;
GetWindowBounds(effectWRef, kWindowContentRgn, &rv);
cid.signature = 'SfUI';
HIViewFindByID(root, cid, &ctl);
HIViewGetFrame(ctl, &frame);
frame.size.width = (float) (rv.right - rv.left);
HIViewSetFrame(ctl, &frame);
cid.signature = 'LINE';
HIViewFindByID(root, cid, &ctl);
HIViewGetFrame(ctl, &frame);
frame.size.width = (float) (rv.right - rv.left - 24);
HIViewSetFrame(ctl, &frame);
rct.top = 0;
rct.left = 0;
rct.bottom = rv.bottom - rv.top;
rct.right = rv.right - rv.left;
err = InvalWindowRect(effectWRef, &rct);
}
#endif
}
void ConfigureSoundEffects (void) void ConfigureSoundEffects (void)
{ {
OSStatus err; // OSStatus err;
IBNibRef nibRef; // IBNibRef nibRef;
//
err = CreateNibReference(kMacS9XCFString, &nibRef); // err = CreateNibReference(kMacS9XCFString, &nibRef);
if (err == noErr) // if (err == noErr)
{ // {
WindowRef uiparts; // WindowRef uiparts;
//
err = CreateWindowFromNib(nibRef, CFSTR("SoundEffect"), &uiparts); // err = CreateWindowFromNib(nibRef, CFSTR("SoundEffect"), &uiparts);
if (err == noErr) // if (err == noErr)
{ // {
EventHandlerUPP eventUPP; // EventHandlerUPP eventUPP;
EventHandlerRef eventHandler; // EventHandlerRef eventHandler;
EventTypeSpec event[] = { { kEventClassWindow, kEventWindowClose }, // EventTypeSpec event[] = { { kEventClassWindow, kEventWindowClose },
{ kEventClassCommand, kEventCommandProcess }, // { kEventClassCommand, kEventCommandProcess },
{ kEventClassCommand, kEventCommandUpdateStatus } }; // { kEventClassCommand, kEventCommandUpdateStatus } };
HIViewRef ctl, userpane, contentview; // HIViewRef ctl, userpane, contentview;
HIViewID cid; // HIViewID cid;
CFStringRef str; // CFStringRef str;
Rect rct; // Rect rct;
WindowAttributes metal = 0; // WindowAttributes metal = 0;
//
cid.id = 0; // cid.id = 0;
cid.signature = 'SfUI'; // cid.signature = 'SfUI';
HIViewFindByID(HIViewGetRoot(uiparts), cid, &userpane); // HIViewFindByID(HIViewGetRoot(uiparts), cid, &userpane);
GetWindowBounds(uiparts, kWindowContentRgn, &rct); // GetWindowBounds(uiparts, kWindowContentRgn, &rct);
//
if (systemVersion >= 0x1040) // AUs support compositing // if (systemVersion >= 0x1040) // AUs support compositing
{ // {
HIRect frame; // HIRect frame;
//
str = CFCopyLocalizedString(CFSTR("CreateMetalDlg"), "NO"); // str = CFCopyLocalizedString(CFSTR("CreateMetalDlg"), "NO");
if (str) // if (str)
{ // {
if (CFStringCompare(str, CFSTR("YES"), 0) == kCFCompareEqualTo) // if (CFStringCompare(str, CFSTR("YES"), 0) == kCFCompareEqualTo)
metal = kWindowMetalAttribute; // metal = kWindowMetalAttribute;
//
CFRelease(str); // CFRelease(str);
} // }
//
frame = CGRectMake(0.0f, 0.0f, (float) (rct.right - rct.left), (float) (rct.bottom - rct.top)); // frame = CGRectMake(0.0f, 0.0f, (float) (rct.right - rct.left), (float) (rct.bottom - rct.top));
err = CreateNewWindow(kDocumentWindowClass, kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute | kWindowCompositingAttribute | metal, &rct, &effectWRef); // err = CreateNewWindow(kDocumentWindowClass, kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute | kWindowCompositingAttribute | metal, &rct, &effectWRef);
err = HIViewFindByID(HIViewGetRoot(effectWRef), kHIViewWindowContentID, &contentview); // err = HIViewFindByID(HIViewGetRoot(effectWRef), kHIViewWindowContentID, &contentview);
err = HIViewAddSubview(contentview, userpane); // err = HIViewAddSubview(contentview, userpane);
err = HIViewSetFrame(userpane, &frame); // err = HIViewSetFrame(userpane, &frame);
} // }
#ifdef MAC_PANTHER_SUPPORT // #ifdef MAC_PANTHER_SUPPORT
else // else
{ // {
err = CreateNewWindow(kDocumentWindowClass, kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute, &rct, &effectWRef); // err = CreateNewWindow(kDocumentWindowClass, kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute, &rct, &effectWRef);
err = CreateRootControl(effectWRef, &contentview); // err = CreateRootControl(effectWRef, &contentview);
err = EmbedControl(userpane, contentview); // err = EmbedControl(userpane, contentview);
MoveControl(userpane, 0, 0); // MoveControl(userpane, 0, 0);
} // }
#endif // #endif
//
CFRelease(uiparts); // CFRelease(uiparts);
//
if (!metal) // if (!metal)
err = SetThemeWindowBackground(effectWRef, kThemeBrushDialogBackgroundActive, false); // err = SetThemeWindowBackground(effectWRef, kThemeBrushDialogBackgroundActive, false);
//
str = CFCopyLocalizedString(CFSTR("SoundEffectDlg"), "SoundEffect"); // str = CFCopyLocalizedString(CFSTR("SoundEffectDlg"), "SoundEffect");
if (str) // if (str)
{ // {
err = SetWindowTitleWithCFString(effectWRef, str); // err = SetWindowTitleWithCFString(effectWRef, str);
CFRelease(str); // CFRelease(str);
} // }
//
if (systemVersion >= 0x1040) // AUs support compositing // if (systemVersion >= 0x1040) // AUs support compositing
{ // {
HILayoutInfo layoutinfo; // HILayoutInfo layoutinfo;
HIViewRef separator; // HIViewRef separator;
//
cid.signature = 'LINE'; // cid.signature = 'LINE';
err = HIViewFindByID(userpane, cid, &separator); // err = HIViewFindByID(userpane, cid, &separator);
//
layoutinfo.version = kHILayoutInfoVersionZero; // layoutinfo.version = kHILayoutInfoVersionZero;
err = HIViewGetLayoutInfo(userpane, &layoutinfo); // err = HIViewGetLayoutInfo(userpane, &layoutinfo);
//
layoutinfo.binding.top.toView = contentview; // layoutinfo.binding.top.toView = contentview;
layoutinfo.binding.top.kind = kHILayoutBindNone; // layoutinfo.binding.top.kind = kHILayoutBindNone;
layoutinfo.binding.bottom.toView = contentview; // layoutinfo.binding.bottom.toView = contentview;
layoutinfo.binding.bottom.kind = kHILayoutBindNone; // layoutinfo.binding.bottom.kind = kHILayoutBindNone;
layoutinfo.binding.left.toView = contentview; // layoutinfo.binding.left.toView = contentview;
layoutinfo.binding.left.kind = kHILayoutBindLeft; // layoutinfo.binding.left.kind = kHILayoutBindLeft;
layoutinfo.binding.right.toView = contentview; // layoutinfo.binding.right.toView = contentview;
layoutinfo.binding.right.kind = kHILayoutBindRight; // layoutinfo.binding.right.kind = kHILayoutBindRight;
err = HIViewSetLayoutInfo(userpane, &layoutinfo); // err = HIViewSetLayoutInfo(userpane, &layoutinfo);
//
layoutinfo.version = kHILayoutInfoVersionZero; // layoutinfo.version = kHILayoutInfoVersionZero;
err = HIViewGetLayoutInfo(separator, &layoutinfo); // err = HIViewGetLayoutInfo(separator, &layoutinfo);
//
layoutinfo.binding.top.toView = userpane; // layoutinfo.binding.top.toView = userpane;
layoutinfo.binding.top.kind = kHILayoutBindNone; // layoutinfo.binding.top.kind = kHILayoutBindNone;
layoutinfo.binding.bottom.toView = userpane; // layoutinfo.binding.bottom.toView = userpane;
layoutinfo.binding.bottom.kind = kHILayoutBindNone; // layoutinfo.binding.bottom.kind = kHILayoutBindNone;
layoutinfo.binding.left.toView = userpane; // layoutinfo.binding.left.toView = userpane;
layoutinfo.binding.left.kind = kHILayoutBindLeft; // layoutinfo.binding.left.kind = kHILayoutBindLeft;
layoutinfo.binding.right.toView = userpane; // layoutinfo.binding.right.toView = userpane;
layoutinfo.binding.right.kind = kHILayoutBindRight; // layoutinfo.binding.right.kind = kHILayoutBindRight;
err = HIViewSetLayoutInfo(separator, &layoutinfo); // err = HIViewSetLayoutInfo(separator, &layoutinfo);
} // }
//
eventUPP = NewEventHandlerUPP(SoundEffectsEventHandler); // eventUPP = NewEventHandlerUPP(SoundEffectsEventHandler);
err = InstallWindowEventHandler(effectWRef, eventUPP, GetEventTypeCount(event), event, (void *) effectWRef, &eventHandler); // err = InstallWindowEventHandler(effectWRef, eventUPP, GetEventTypeCount(event), event, (void *) effectWRef, &eventHandler);
//
GetWindowBounds(effectWRef, kWindowContentRgn, &rct); // GetWindowBounds(effectWRef, kWindowContentRgn, &rct);
effectWSize.width = (float) (rct.right - rct.left); // effectWSize.width = (float) (rct.right - rct.left);
effectWSize.height = (float) (rct.bottom - rct.top ); // effectWSize.height = (float) (rct.bottom - rct.top );
//
carbonView = NULL; // carbonView = NULL;
ReplaceAudioUnitCarbonView(); // ReplaceAudioUnitCarbonView();
//
cid.signature = 'Epop'; // cid.signature = 'Epop';
HIViewFindByID(userpane, cid, &ctl); // HIViewFindByID(userpane, cid, &ctl);
switch (cureffect) // switch (cureffect)
{ // {
case kAUReverb: // case kAUReverb:
SetControl32BitValue(ctl, 1); // SetControl32BitValue(ctl, 1);
break; // break;
//
case kAUGraphEQ: // case kAUGraphEQ:
SetControl32BitValue(ctl, 2); // SetControl32BitValue(ctl, 2);
break; // break;
} // }
//
MoveWindowPosition(effectWRef, kWindowSoundEffect, false); // MoveWindowPosition(effectWRef, kWindowSoundEffect, false);
ShowWindow(effectWRef); // ShowWindow(effectWRef);
err = RunAppModalLoopForWindow(effectWRef); // err = RunAppModalLoopForWindow(effectWRef);
HideWindow(effectWRef); // HideWindow(effectWRef);
SaveWindowPosition(effectWRef, kWindowSoundEffect); // SaveWindowPosition(effectWRef, kWindowSoundEffect);
//
if (carbonView) // if (carbonView)
{ // {
err = RemoveEventHandler(carbonViewEventRef); // err = RemoveEventHandler(carbonViewEventRef);
DisposeEventHandlerUPP(carbonViewEventUPP); // DisposeEventHandlerUPP(carbonViewEventUPP);
carbonViewEventRef = NULL; // carbonViewEventRef = NULL;
carbonViewEventUPP = NULL; // carbonViewEventUPP = NULL;
//
CloseComponent(carbonView); // CloseComponent(carbonView);
carbonView = NULL; // carbonView = NULL;
} // }
//
err = RemoveEventHandler(eventHandler); // err = RemoveEventHandler(eventHandler);
DisposeEventHandlerUPP(eventUPP); // DisposeEventHandlerUPP(eventUPP);
//
CFRelease(effectWRef); // CFRelease(effectWRef);
} // }
//
DisposeNibReference(nibRef); // DisposeNibReference(nibRef);
} // }
}
static pascal OSStatus SoundEffectsCarbonViewEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
{
OSStatus err, result = eventNotHandledErr;
HIViewRef ctl;
HIRect bounds;
switch (GetEventClass(inEvent))
{
case kEventClassControl:
switch (GetEventKind(inEvent))
{
case kEventControlBoundsChanged:
err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &ctl);
if (err == noErr)
{
err = GetEventParameter(inEvent, kEventParamCurrentBounds, typeHIRect, NULL, sizeof(HIRect), NULL, &bounds);
if (err == noErr)
{
if ((bounds.size.width > 0) && (bounds.size.height > 0))
ResizeSoundEffectsDialog(ctl);
}
}
result = noErr;
break;
}
break;
}
return (result);
}
static pascal OSStatus SoundEffectsEventHandler (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;
}
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 'Enab':
{
Boolean r = false;
mboxPause = true;
err = AUGraphIsRunning(agraph, &r);
if (err == noErr && r)
err = AUGraphStop(agraph);
DisconnectAudioUnits();
err = AUGraphUninitialize(agraph);
aueffect ^= cureffect;
SetAudioUnitSoundFormat();
ChangeBufferFrameSize();
err = AUGraphInitialize(agraph);
ConnectAudioUnits();
if (r)
err = AUGraphStart(agraph);
mboxPause = false;
result = noErr;
break;
}
case 'Revb':
cureffect = kAUReverb;
ReplaceAudioUnitCarbonView();
break;
case 'GrEQ':
cureffect = kAUGraphEQ;
ReplaceAudioUnitCarbonView();
break;
}
}
break;
}
break;
}
return (result);
} }

View File

@ -15,21 +15,21 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/
#ifndef _mac_cart_h_ #ifndef _mac_cart_h_
#define _mac_cart_h_ #define _mac_cart_h_
bool8 NavOpenROMImage (FSRef *); #import <Cocoa/Cocoa.h>
bool8 NavBeginOpenROMImageSheet (WindowRef, CFStringRef);
bool8 NavEndOpenROMImageSheet (FSRef *); NSURL *NavOpenROMImage ();
bool8 NavBeginChooseFolderSheet (WindowRef); NSURL *NavChooseFolderSheet (NSWindow *);
bool8 NavEndChooseFolderSheet (FSRef *); NSURL *NavFreezeTo ();
bool8 NavFreezeTo (char *); NSURL *NavDefrostFrom ();
bool8 NavDefrostFrom (char *); NSURL *NavRecordMovieTo ();
bool8 NavRecordMovieTo (char *); NSURL *NavPlayMovieFrom ();
bool8 NavPlayMovieFrom (char *); NSURL *NavQTMovieRecordTo ();
bool8 NavQTMovieRecordTo (char *);
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,594 +0,0 @@
/*****************************************************************************\
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 "port.h"
#include "cheats.h"
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include "mac-prefix.h"
#include "mac-dialog.h"
#include "mac-os.h"
#include "mac-stringtools.h"
#include "mac-cheat.h"
#define kDataBrowser 'BRSR'
#define kCmCheckBox 'CHK_'
#define kCmAddress 'ADDR'
#define kCmValue 'VALU'
#define kCmDescription 'DESC'
#define kNewButton 'NEW_'
#define kDelButton 'DEL_'
#define kAllButton 'ALL_'
extern SCheatData Cheat;
typedef struct
{
uint32 id;
uint32 address;
uint8 value;
bool8 valid;
bool8 enabled;
char description[22];
} CheatItem;
static WindowRef wRef;
static HIViewRef dbRef;
static CheatItem citem[MAC_MAX_CHEATS];
static uint32 numofcheats;
static void InitCheatItems (void);
static void ImportCheatItems (void);
static void DetachCheatItems (void);
static void AddCheatItem (void);
static void DeleteCheatItem (void);
static void EnableAllCheatItems (void);
static pascal void DBItemNotificationCallBack (HIViewRef, DataBrowserItemID, DataBrowserItemNotification);
static pascal Boolean DBCompareCallBack (HIViewRef, DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID);
static pascal OSStatus DBClientDataCallback (HIViewRef, DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemDataRef, Boolean);
static pascal OSStatus CheatEventHandler (EventHandlerCallRef, EventRef, void *);
static void InitCheatItems (void)
{
for (unsigned int i = 0; i < MAC_MAX_CHEATS; i++)
{
citem[i].id = i + 1;
citem[i].valid = false;
citem[i].enabled = false;
citem[i].address = 0;
citem[i].value = 0;
sprintf(citem[i].description, "Cheat %03" PRIu32, citem[i].id);
}
}
static void ImportCheatItems (void)
{
int cheat_num = std::min((int)Cheat.g.size(), MAC_MAX_CHEATS);
for (unsigned int i = 0; i < cheat_num; i++)
{
citem[i].valid = true;
citem[i].enabled = Cheat.g[i].enabled;
citem[i].address = Cheat.g[i].c[0].address; // mac dialog only supports one cheat per group at the moment
citem[i].value = Cheat.g[i].c[0].byte;
strncpy(citem[i].description, Cheat.g[i].name, 21);
citem[i].description[21] = '\0';
}
}
static void DetachCheatItems (void)
{
S9xDeleteCheats();
for (unsigned int i = 0; i < MAC_MAX_CHEATS; i++)
{
if (citem[i].valid)
{
char code[10];
snprintf(code, 10, "%x=%x", citem[i].address, citem[i].value);
int index = S9xAddCheatGroup(citem[i].description, code);
if(citem[i].enabled && index >= 0)
S9xEnableCheatGroup(index);
}
}
}
void ConfigureCheat (void)
{
if (!cartOpen)
return;
OSStatus err;
IBNibRef nibRef;
err = CreateNibReference(kMacS9XCFString, &nibRef);
if (err == noErr)
{
err = CreateWindowFromNib(nibRef, CFSTR("CheatEntry"), &wRef);
if (err == noErr)
{
DataBrowserCallbacks callbacks;
EventHandlerRef eref;
EventHandlerUPP eUPP;
EventTypeSpec events[] = { { kEventClassCommand, kEventCommandProcess },
{ kEventClassCommand, kEventCommandUpdateStatus },
{ kEventClassWindow, kEventWindowClose } };
HIViewRef ctl, root;
HIViewID cid;
root = HIViewGetRoot(wRef);
cid.id = 0;
cid.signature = kDataBrowser;
HIViewFindByID(root, cid, &dbRef);
#ifdef MAC_PANTHER_SUPPORT
if (systemVersion < 0x1040)
{
HISize minSize;
Rect rct;
GetWindowBounds(wRef, kWindowContentRgn, &rct);
minSize.width = (float) (rct.right - rct.left);
minSize.height = (float) (rct.bottom - rct.top );
err = SetWindowResizeLimits(wRef, &minSize, NULL);
}
#endif
callbacks.version = kDataBrowserLatestCallbacks;
err = InitDataBrowserCallbacks(&callbacks);
callbacks.u.v1.itemDataCallback = NewDataBrowserItemDataUPP(DBClientDataCallback);
callbacks.u.v1.itemCompareCallback = NewDataBrowserItemCompareUPP(DBCompareCallBack);
callbacks.u.v1.itemNotificationCallback = NewDataBrowserItemNotificationUPP(DBItemNotificationCallBack);
err = SetDataBrowserCallbacks(dbRef, &callbacks);
if (systemVersion >= 0x1040)
err = DataBrowserChangeAttributes(dbRef, kDataBrowserAttributeListViewAlternatingRowColors, kDataBrowserAttributeNone);
InitCheatItems();
ImportCheatItems();
DataBrowserItemID *id;
id = new DataBrowserItemID[MAC_MAX_CHEATS];
if (!id)
QuitWithFatalError(0, "cheat 01");
numofcheats = 0;
for (unsigned int i = 0; i < MAC_MAX_CHEATS; i++)
{
if (citem[i].valid)
{
id[numofcheats] = citem[i].id;
numofcheats++;
}
}
if (numofcheats)
err = AddDataBrowserItems(dbRef, kDataBrowserNoItem, numofcheats, id, kDataBrowserItemNoProperty);
delete [] id;
cid.signature = kNewButton;
HIViewFindByID(root, cid, &ctl);
if (numofcheats == MAC_MAX_CHEATS)
err = DeactivateControl(ctl);
else
err = ActivateControl(ctl);
cid.signature = kAllButton;
HIViewFindByID(root, cid, &ctl);
if (numofcheats == 0)
err = DeactivateControl(ctl);
else
err = ActivateControl(ctl);
cid.signature = kDelButton;
HIViewFindByID(root, cid, &ctl);
err = DeactivateControl(ctl);
eUPP = NewEventHandlerUPP(CheatEventHandler);
err = InstallWindowEventHandler(wRef, eUPP, GetEventTypeCount(events), events, (void *) wRef, &eref);
err = SetKeyboardFocus(wRef, dbRef, kControlFocusNextPart);
MoveWindowPosition(wRef, kWindowCheatEntry, true);
ShowWindow(wRef);
err = RunAppModalLoopForWindow(wRef);
HideWindow(wRef);
SaveWindowPosition(wRef, kWindowCheatEntry);
err = RemoveEventHandler(eref);
DisposeEventHandlerUPP(eUPP);
DisposeDataBrowserItemNotificationUPP(callbacks.u.v1.itemNotificationCallback);
DisposeDataBrowserItemCompareUPP(callbacks.u.v1.itemCompareCallback);
DisposeDataBrowserItemDataUPP(callbacks.u.v1.itemDataCallback);
CFRelease(wRef);
DetachCheatItems();
}
DisposeNibReference(nibRef);
}
}
static void AddCheatItem (void)
{
OSStatus err;
HIViewRef ctl, root;
HIViewID cid;
DataBrowserItemID id[1];
unsigned int i;
if (numofcheats == MAC_MAX_CHEATS)
return;
for (i = 0; i < MAC_MAX_CHEATS; i++)
if (citem[i].valid == false)
break;
if (i == MAC_MAX_CHEATS)
return;
numofcheats++;
citem[i].valid = true;
citem[i].enabled = false;
citem[i].address = 0;
citem[i].value = 0;
sprintf(citem[i].description, "Cheat %03" PRIu32, citem[i].id);
id[0] = citem[i].id;
err = AddDataBrowserItems(dbRef, kDataBrowserNoItem, 1, id, kDataBrowserItemNoProperty);
err = RevealDataBrowserItem(dbRef, id[0], kCmAddress, true);
root = HIViewGetRoot(wRef);
cid.id = 0;
if (numofcheats == MAC_MAX_CHEATS)
{
cid.signature = kNewButton;
HIViewFindByID(root, cid, &ctl);
err = DeactivateControl(ctl);
}
if (numofcheats)
{
cid.signature = kAllButton;
HIViewFindByID(root, cid, &ctl);
err = ActivateControl(ctl);
}
}
static void DeleteCheatItem (void)
{
OSStatus err;
HIViewRef ctl, root;
HIViewID cid;
Handle selectedItems;
ItemCount selectionCount;
selectedItems = NewHandle(0);
if (!selectedItems)
return;
err = GetDataBrowserItems(dbRef, kDataBrowserNoItem, true, kDataBrowserItemIsSelected, selectedItems);
selectionCount = (GetHandleSize(selectedItems) / sizeof(DataBrowserItemID));
if (selectionCount == 0)
{
DisposeHandle(selectedItems);
return;
}
err = RemoveDataBrowserItems(dbRef, kDataBrowserNoItem, selectionCount, (DataBrowserItemID *) *selectedItems, kDataBrowserItemNoProperty);
for (unsigned int i = 0; i < selectionCount; i++)
{
citem[((DataBrowserItemID *) (*selectedItems))[i] - 1].valid = false;
citem[((DataBrowserItemID *) (*selectedItems))[i] - 1].enabled = false;
numofcheats--;
}
DisposeHandle(selectedItems);
root = HIViewGetRoot(wRef);
cid.id = 0;
if (numofcheats < MAC_MAX_CHEATS)
{
cid.signature = kNewButton;
HIViewFindByID(root, cid, &ctl);
err = ActivateControl(ctl);
}
if (numofcheats == 0)
{
cid.signature = kAllButton;
HIViewFindByID(root, cid, &ctl);
err = DeactivateControl(ctl);
}
}
static void EnableAllCheatItems (void)
{
OSStatus err;
for (unsigned int i = 0; i < MAC_MAX_CHEATS; i++)
if (citem[i].valid)
citem[i].enabled = true;
err = UpdateDataBrowserItems(dbRef, kDataBrowserNoItem, kDataBrowserNoItem, NULL, kDataBrowserItemNoProperty, kCmCheckBox);
}
static pascal OSStatus DBClientDataCallback (HIViewRef browser, DataBrowserItemID itemID, DataBrowserPropertyID property, DataBrowserItemDataRef itemData, Boolean changeValue)
{
OSStatus err, result;
CFStringRef str;
Boolean r;
uint32 address;
uint8 value;
char code[256];
result = noErr;
switch (property)
{
case kCmCheckBox:
ThemeButtonValue buttonValue;
if (changeValue)
{
err = GetDataBrowserItemDataButtonValue(itemData, &buttonValue);
citem[itemID - 1].enabled = (buttonValue == kThemeButtonOn) ? true : false;
}
else
err = SetDataBrowserItemDataButtonValue(itemData, citem[itemID - 1].enabled ? kThemeButtonOn : kThemeButtonOff);
break;
case kCmAddress:
if (changeValue)
{
err = GetDataBrowserItemDataText(itemData, &str);
r = CFStringGetCString(str, code, 256, CFStringGetSystemEncoding());
CFRelease(str);
if (r)
{
Boolean translated;
if (S9xProActionReplayToRaw(code, address, value) == NULL)
translated = true;
else
if (S9xGameGenieToRaw(code, address, value) == NULL)
translated = true;
else
{
translated = false;
if (sscanf(code, "%" SCNx32, &address) != 1)
address = 0;
else
address &= 0xFFFFFF;
}
citem[itemID - 1].address = address;
sprintf(code, "%06" PRIX32, address);
str = CFStringCreateWithCString(kCFAllocatorDefault, code, CFStringGetSystemEncoding());
err = SetDataBrowserItemDataText(itemData, str);
CFRelease(str);
if (translated)
{
DataBrowserItemID id[1];
citem[itemID - 1].value = value;
id[0] = itemID;
err = UpdateDataBrowserItems(browser, kDataBrowserNoItem, 1, id, kDataBrowserItemNoProperty, kCmValue);
}
}
}
else
{
sprintf(code, "%06" PRIX32, citem[itemID - 1].address);
str = CFStringCreateWithCString(kCFAllocatorDefault, code, CFStringGetSystemEncoding());
err = SetDataBrowserItemDataText(itemData, str);
CFRelease(str);
}
break;
case kCmValue:
if (changeValue)
{
err = GetDataBrowserItemDataText(itemData, &str);
r = CFStringGetCString(str, code, 256, CFStringGetSystemEncoding());
CFRelease(str);
if (r)
{
uint32 byte;
if (sscanf(code, "%" SCNx32, &byte) == 1)
citem[itemID - 1].value = (uint8) byte;
else
{
citem[itemID - 1].value = 0;
err = SetDataBrowserItemDataText(itemData, CFSTR("00"));
}
}
}
else
{
sprintf(code, "%02" PRIX8, citem[itemID - 1].value);
str = CFStringCreateWithCString(kCFAllocatorDefault, code, CFStringGetSystemEncoding());
err = SetDataBrowserItemDataText(itemData, str);
CFRelease(str);
}
break;
case kCmDescription:
if (changeValue)
{
code[0] = 0;
err = GetDataBrowserItemDataText(itemData, &str);
strcpy(code, GetMultiByteCharacters(str, 19));
CFRelease(str);
if (code[0] == 0)
{
code[0] = ' ';
code[1] = 0;
}
strcpy(citem[itemID - 1].description, code);
}
else
{
str = CFStringCreateWithCString(kCFAllocatorDefault, citem[itemID - 1].description, CFStringGetSystemEncoding());
err = SetDataBrowserItemDataText(itemData, str);
CFRelease(str);
}
break;
case kDataBrowserItemIsActiveProperty:
err = SetDataBrowserItemDataBooleanValue(itemData, true);
break;
case kDataBrowserItemIsEditableProperty:
err = SetDataBrowserItemDataBooleanValue(itemData, true);
break;
default:
result = errDataBrowserPropertyNotSupported;
}
return (result);
}
static pascal Boolean DBCompareCallBack (HIViewRef browser, DataBrowserItemID itemOne, DataBrowserItemID itemTwo, DataBrowserPropertyID sortProperty)
{
Boolean result = false;
switch (sortProperty)
{
case kCmCheckBox:
result = (citem[itemOne - 1].enabled && !(citem[itemTwo - 1].enabled)) ? true : false;
break;
case kCmAddress:
result = (citem[itemOne - 1].address < citem[itemTwo - 1].address) ? true : false;
break;
case kCmValue:
result = (citem[itemOne - 1].value < citem[itemTwo - 1].value) ? true : false;
break;
case kCmDescription:
result = (strcmp(citem[itemOne - 1].description, citem[itemTwo - 1].description) < 0) ? true : false;
}
return (result);
}
static pascal void DBItemNotificationCallBack (HIViewRef browser, DataBrowserItemID itemID, DataBrowserItemNotification message)
{
OSStatus err;
HIViewRef ctl;
HIViewID cid = { kDelButton, 0 };
ItemCount selectionCount;
switch (message)
{
case kDataBrowserSelectionSetChanged:
HIViewFindByID(HIViewGetRoot(wRef), cid, &ctl);
err = GetDataBrowserItemCount(browser, kDataBrowserNoItem, true, kDataBrowserItemIsSelected, &selectionCount);
if (selectionCount == 0)
err = DeactivateControl(ctl);
else
err = ActivateControl(ctl);
}
}
static pascal OSStatus CheatEventHandler (EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
{
OSStatus err, result = eventNotHandledErr;
WindowRef tWindowRef;
tWindowRef = (WindowRef) inUserData;
switch (GetEventClass(inEvent))
{
case kEventClassWindow:
switch (GetEventKind(inEvent))
{
case kEventWindowClose:
QuitAppModalLoopForWindow(tWindowRef);
result = noErr;
break;
}
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 kNewButton:
AddCheatItem();
result = noErr;
break;
case kDelButton:
DeleteCheatItem();
result = noErr;
break;
case kAllButton:
EnableAllCheatItems();
result = noErr;
}
}
}
}
return (result);
}

View File

@ -15,6 +15,7 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/

551
macosx/mac-cheat.mm Executable file
View File

@ -0,0 +1,551 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#include "port.h"
#include "cheats.h"
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include "mac-prefix.h"
#include "mac-dialog.h"
#include "mac-os.h"
#include "mac-stringtools.h"
#include "mac-cheat.h"
#define kDataBrowser 'BRSR'
#define kCmCheckBox 'CHK_'
#define kCmAddress 'ADDR'
#define kCmValue 'VALU'
#define kCmDescription 'DESC'
#define kNewButton 'NEW_'
#define kDelButton 'DEL_'
#define kAllButton 'ALL_'
extern SCheatData Cheat;
typedef struct
{
uint32 id;
uint32 address;
uint8 value;
bool8 valid;
bool8 enabled;
char description[22];
} CheatItem;
static WindowRef wRef;
static HIViewRef dbRef;
static CheatItem citem[MAC_MAX_CHEATS];
static uint32 numofcheats;
static void InitCheatItems (void);
static void ImportCheatItems (void);
static void DetachCheatItems (void);
static void AddCheatItem (void);
static void DeleteCheatItem (void);
static void EnableAllCheatItems (void);
static void DBItemNotificationCallBack (HIViewRef, DataBrowserItemID, DataBrowserItemNotification);
static OSStatus CheatEventHandler (EventHandlerCallRef, EventRef, void *);
static void InitCheatItems (void)
{
for (unsigned int i = 0; i < MAC_MAX_CHEATS; i++)
{
citem[i].id = i + 1;
citem[i].valid = false;
citem[i].enabled = false;
citem[i].address = 0;
citem[i].value = 0;
sprintf(citem[i].description, "Cheat %03" PRIu32, citem[i].id);
}
}
static void ImportCheatItems (void)
{
int cheat_num = std::min((int)Cheat.g.size(), MAC_MAX_CHEATS);
for (unsigned int i = 0; i < cheat_num; i++)
{
citem[i].valid = true;
citem[i].enabled = Cheat.g[i].enabled;
citem[i].address = Cheat.g[i].c[0].address; // mac dialog only supports one cheat per group at the moment
citem[i].value = Cheat.g[i].c[0].byte;
strncpy(citem[i].description, Cheat.g[i].name, 21);
citem[i].description[21] = '\0';
}
}
static void DetachCheatItems (void)
{
S9xDeleteCheats();
for (unsigned int i = 0; i < MAC_MAX_CHEATS; i++)
{
if (citem[i].valid)
{
char code[10];
snprintf(code, 10, "%x=%x", citem[i].address, citem[i].value);
int index = S9xAddCheatGroup(citem[i].description, code);
if(citem[i].enabled && index >= 0)
S9xEnableCheatGroup(index);
}
}
}
void ConfigureCheat (void)
{
if (!cartOpen)
return;
// OSStatus err;
// IBNibRef nibRef;
//
// err = CreateNibReference(kMacS9XCFString, &nibRef);
// if (err == noErr)
// {
// err = CreateWindowFromNib(nibRef, CFSTR("CheatEntry"), &wRef);
// if (err == noErr)
// {
// DataBrowserCallbacks callbacks;
// EventHandlerRef eref;
// EventHandlerUPP eUPP;
// EventTypeSpec events[] = { { kEventClassCommand, kEventCommandProcess },
// { kEventClassCommand, kEventCommandUpdateStatus },
// { kEventClassWindow, kEventWindowClose } };
// HIViewRef ctl, root;
// HIViewID cid;
//
// root = HIViewGetRoot(wRef);
// cid.id = 0;
// cid.signature = kDataBrowser;
// HIViewFindByID(root, cid, &dbRef);
//
// #ifdef MAC_PANTHER_SUPPORT
// if (systemVersion < 0x1040)
// {
// HISize minSize;
// Rect rct;
//
// GetWindowBounds(wRef, kWindowContentRgn, &rct);
// minSize.width = (float) (rct.right - rct.left);
// minSize.height = (float) (rct.bottom - rct.top );
// err = SetWindowResizeLimits(wRef, &minSize, NULL);
// }
// #endif
//
// callbacks.version = kDataBrowserLatestCallbacks;
// err = InitDataBrowserCallbacks(&callbacks);
// callbacks.u.v1.itemDataCallback = NewDataBrowserItemDataUPP(DBClientDataCallback);
// callbacks.u.v1.itemCompareCallback = NewDataBrowserItemCompareUPP(DBCompareCallBack);
// callbacks.u.v1.itemNotificationCallback = NewDataBrowserItemNotificationUPP(DBItemNotificationCallBack);
// err = SetDataBrowserCallbacks(dbRef, &callbacks);
//
// if (systemVersion >= 0x1040)
// err = DataBrowserChangeAttributes(dbRef, kDataBrowserAttributeListViewAlternatingRowColors, kDataBrowserAttributeNone);
//
// InitCheatItems();
// ImportCheatItems();
//
// DataBrowserItemID *id;
//
// id = new DataBrowserItemID[MAC_MAX_CHEATS];
// if (!id)
// QuitWithFatalError(@"cheat 01");
//
// numofcheats = 0;
//
// for (unsigned int i = 0; i < MAC_MAX_CHEATS; i++)
// {
// if (citem[i].valid)
// {
// id[numofcheats] = citem[i].id;
// numofcheats++;
// }
// }
//
// if (numofcheats)
// err = AddDataBrowserItems(dbRef, kDataBrowserNoItem, numofcheats, id, kDataBrowserItemNoProperty);
//
// delete [] id;
//
// cid.signature = kNewButton;
// HIViewFindByID(root, cid, &ctl);
// if (numofcheats == MAC_MAX_CHEATS)
// err = DeactivateControl(ctl);
// else
// err = ActivateControl(ctl);
//
// cid.signature = kAllButton;
// HIViewFindByID(root, cid, &ctl);
// if (numofcheats == 0)
// err = DeactivateControl(ctl);
// else
// err = ActivateControl(ctl);
//
// cid.signature = kDelButton;
// HIViewFindByID(root, cid, &ctl);
// err = DeactivateControl(ctl);
//
// eUPP = NewEventHandlerUPP(CheatEventHandler);
// err = InstallWindowEventHandler(wRef, eUPP, GetEventTypeCount(events), events, (void *) wRef, &eref);
//
// err = SetKeyboardFocus(wRef, dbRef, kControlFocusNextPart);
//
// MoveWindowPosition(wRef, kWindowCheatEntry, true);
// ShowWindow(wRef);
// err = RunAppModalLoopForWindow(wRef);
// HideWindow(wRef);
// SaveWindowPosition(wRef, kWindowCheatEntry);
//
// err = RemoveEventHandler(eref);
// DisposeEventHandlerUPP(eUPP);
//
// DisposeDataBrowserItemNotificationUPP(callbacks.u.v1.itemNotificationCallback);
// DisposeDataBrowserItemCompareUPP(callbacks.u.v1.itemCompareCallback);
// DisposeDataBrowserItemDataUPP(callbacks.u.v1.itemDataCallback);
//
// CFRelease(wRef);
//
// DetachCheatItems();
// }
//
// DisposeNibReference(nibRef);
// }
}
static void AddCheatItem (void)
{
// OSStatus err;
// HIViewRef ctl, root;
// HIViewID cid;
// DataBrowserItemID id[1];
// unsigned int i;
//
// if (numofcheats == MAC_MAX_CHEATS)
// return;
//
// for (i = 0; i < MAC_MAX_CHEATS; i++)
// if (citem[i].valid == false)
// break;
//
// if (i == MAC_MAX_CHEATS)
// return;
//
// numofcheats++;
// citem[i].valid = true;
// citem[i].enabled = false;
// citem[i].address = 0;
// citem[i].value = 0;
// sprintf(citem[i].description, "Cheat %03" PRIu32, citem[i].id);
//
// id[0] = citem[i].id;
// err = AddDataBrowserItems(dbRef, kDataBrowserNoItem, 1, id, kDataBrowserItemNoProperty);
// err = RevealDataBrowserItem(dbRef, id[0], kCmAddress, true);
//
// root = HIViewGetRoot(wRef);
// cid.id = 0;
//
// if (numofcheats == MAC_MAX_CHEATS)
// {
// cid.signature = kNewButton;
// HIViewFindByID(root, cid, &ctl);
// err = DeactivateControl(ctl);
// }
//
// if (numofcheats)
// {
// cid.signature = kAllButton;
// HIViewFindByID(root, cid, &ctl);
// err = ActivateControl(ctl);
// }
}
static void DeleteCheatItem (void)
{
// OSStatus err;
// HIViewRef ctl, root;
// HIViewID cid;
// Handle selectedItems;
// ItemCount selectionCount;
//
// selectedItems = NewHandle(0);
// if (!selectedItems)
// return;
//
// err = GetDataBrowserItems(dbRef, kDataBrowserNoItem, true, kDataBrowserItemIsSelected, selectedItems);
// selectionCount = (GetHandleSize(selectedItems) / sizeof(DataBrowserItemID));
//
// if (selectionCount == 0)
// {
// DisposeHandle(selectedItems);
// return;
// }
//
// err = RemoveDataBrowserItems(dbRef, kDataBrowserNoItem, selectionCount, (DataBrowserItemID *) *selectedItems, kDataBrowserItemNoProperty);
//
// for (unsigned int i = 0; i < selectionCount; i++)
// {
// citem[((DataBrowserItemID *) (*selectedItems))[i] - 1].valid = false;
// citem[((DataBrowserItemID *) (*selectedItems))[i] - 1].enabled = false;
// numofcheats--;
// }
//
// DisposeHandle(selectedItems);
//
// root = HIViewGetRoot(wRef);
// cid.id = 0;
//
// if (numofcheats < MAC_MAX_CHEATS)
// {
// cid.signature = kNewButton;
// HIViewFindByID(root, cid, &ctl);
// err = ActivateControl(ctl);
// }
//
// if (numofcheats == 0)
// {
// cid.signature = kAllButton;
// HIViewFindByID(root, cid, &ctl);
// err = DeactivateControl(ctl);
// }
}
static void EnableAllCheatItems (void)
{
// OSStatus err;
//
// for (unsigned int i = 0; i < MAC_MAX_CHEATS; i++)
// if (citem[i].valid)
// citem[i].enabled = true;
//
// err = UpdateDataBrowserItems(dbRef, kDataBrowserNoItem, kDataBrowserNoItem, NULL, kDataBrowserItemNoProperty, kCmCheckBox);
}
static OSStatus DBClientDataCallback (HIViewRef browser, DataBrowserItemID itemID, DataBrowserPropertyID property, DataBrowserItemDataRef itemData, Boolean changeValue)
{
// OSStatus err, result;
// CFStringRef str;
// Boolean r;
// uint32 address;
// uint8 value;
// char code[256];
//
// result = noErr;
//
// switch (property)
// {
// case kCmCheckBox:
// ThemeButtonValue buttonValue;
//
// if (changeValue)
// {
// err = GetDataBrowserItemDataButtonValue(itemData, &buttonValue);
// citem[itemID - 1].enabled = (buttonValue == kThemeButtonOn) ? true : false;
// }
// else
// err = SetDataBrowserItemDataButtonValue(itemData, citem[itemID - 1].enabled ? kThemeButtonOn : kThemeButtonOff);
//
// break;
//
// case kCmAddress:
// if (changeValue)
// {
// err = GetDataBrowserItemDataText(itemData, &str);
// r = CFStringGetCString(str, code, 256, CFStringGetSystemEncoding());
// CFRelease(str);
// if (r)
// {
// Boolean translated;
//
// if (S9xProActionReplayToRaw(code, address, value) == NULL)
// translated = true;
// else
// if (S9xGameGenieToRaw(code, address, value) == NULL)
// translated = true;
// else
// {
// translated = false;
// if (sscanf(code, "%" SCNx32, &address) != 1)
// address = 0;
// else
// address &= 0xFFFFFF;
// }
//
// citem[itemID - 1].address = address;
// sprintf(code, "%06" PRIX32, address);
// str = CFStringCreateWithCString(kCFAllocatorDefault, code, CFStringGetSystemEncoding());
// err = SetDataBrowserItemDataText(itemData, str);
// CFRelease(str);
//
// if (translated)
// {
// DataBrowserItemID id[1];
//
// citem[itemID - 1].value = value;
// id[0] = itemID;
// err = UpdateDataBrowserItems(browser, kDataBrowserNoItem, 1, id, kDataBrowserItemNoProperty, kCmValue);
// }
// }
// }
// else
// {
// sprintf(code, "%06" PRIX32, citem[itemID - 1].address);
// str = CFStringCreateWithCString(kCFAllocatorDefault, code, CFStringGetSystemEncoding());
// err = SetDataBrowserItemDataText(itemData, str);
// CFRelease(str);
// }
//
// break;
//
// case kCmValue:
// if (changeValue)
// {
// err = GetDataBrowserItemDataText(itemData, &str);
// r = CFStringGetCString(str, code, 256, CFStringGetSystemEncoding());
// CFRelease(str);
// if (r)
// {
// uint32 byte;
//
// if (sscanf(code, "%" SCNx32, &byte) == 1)
// citem[itemID - 1].value = (uint8) byte;
// else
// {
// citem[itemID - 1].value = 0;
// err = SetDataBrowserItemDataText(itemData, CFSTR("00"));
// }
// }
// }
// else
// {
// sprintf(code, "%02" PRIX8, citem[itemID - 1].value);
// str = CFStringCreateWithCString(kCFAllocatorDefault, code, CFStringGetSystemEncoding());
// err = SetDataBrowserItemDataText(itemData, str);
// CFRelease(str);
// }
//
// break;
//
// case kCmDescription:
// if (changeValue)
// {
// code[0] = 0;
// err = GetDataBrowserItemDataText(itemData, &str);
// strcpy(code, GetMultiByteCharacters(str, 19));
// CFRelease(str);
//
// if (code[0] == 0)
// {
// code[0] = ' ';
// code[1] = 0;
// }
//
// strcpy(citem[itemID - 1].description, code);
// }
// else
// {
// str = CFStringCreateWithCString(kCFAllocatorDefault, citem[itemID - 1].description, CFStringGetSystemEncoding());
// err = SetDataBrowserItemDataText(itemData, str);
// CFRelease(str);
// }
//
// break;
//
// case kDataBrowserItemIsActiveProperty:
// err = SetDataBrowserItemDataBooleanValue(itemData, true);
// break;
//
// case kDataBrowserItemIsEditableProperty:
// err = SetDataBrowserItemDataBooleanValue(itemData, true);
// break;
//
// default:
// result = errDataBrowserPropertyNotSupported;
// }
//
// return (result);
return 0;
}
static OSStatus CheatEventHandler (EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
{
// OSStatus err, result = eventNotHandledErr;
// WindowRef tWindowRef;
//
// tWindowRef = (WindowRef) inUserData;
//
// switch (GetEventClass(inEvent))
// {
// case kEventClassWindow:
// switch (GetEventKind(inEvent))
// {
// case kEventWindowClose:
// QuitAppModalLoopForWindow(tWindowRef);
// result = noErr;
// break;
// }
//
// 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 kNewButton:
// AddCheatItem();
// result = noErr;
// break;
//
// case kDelButton:
// DeleteCheatItem();
// result = noErr;
// break;
//
// case kAllButton:
// EnableAllCheatItems();
// result = noErr;
// }
// }
// }
// }
//
// return (result);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,7 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/

1237
macosx/mac-cheatfinder.mm Executable file

File diff suppressed because it is too large Load Diff

View File

@ -136,9 +136,9 @@ static bool8 NPClientReplyPhaseSpanTest (void);
static void * NPClientConnectThread (void *); static void * NPClientConnectThread (void *);
static void * NPClientPrepareThread (void *); static void * NPClientPrepareThread (void *);
static void * NPClientNetPlayThread (void *); static void * NPClientNetPlayThread (void *);
static pascal void NPClientDialogTimerHandler (EventLoopTimerRef, void *); static void NPClientDialogTimerHandler (EventLoopTimerRef, void *);
static pascal OSStatus NPClientDialogEventHandler (EventHandlerCallRef, EventRef, void *); static OSStatus NPClientDialogEventHandler (EventHandlerCallRef, EventRef, void *);
static pascal OSStatus NPClientSheetEventHandler (EventHandlerCallRef, EventRef, void *); static OSStatus NPClientSheetEventHandler (EventHandlerCallRef, EventRef, void *);
bool8 NPClientDialog (void) bool8 NPClientDialog (void)
@ -230,7 +230,7 @@ bool8 NPClientDialog (void)
return (!npclient.dialogcancel); return (!npclient.dialogcancel);
} }
static pascal OSStatus NPClientDialogEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) static OSStatus NPClientDialogEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
{ {
OSStatus err, result = eventNotHandledErr; OSStatus err, result = eventNotHandledErr;
@ -335,7 +335,7 @@ static pascal OSStatus NPClientDialogEventHandler (EventHandlerCallRef inHandler
return (result); return (result);
} }
static pascal void NPClientDialogTimerHandler (EventLoopTimerRef inTimer, void *userData) static void NPClientDialogTimerHandler (EventLoopTimerRef inTimer, void *userData)
{ {
WindowRef window = (WindowRef) userData; WindowRef window = (WindowRef) userData;
HIViewRef ctl; HIViewRef ctl;
@ -740,7 +740,7 @@ static bool8 NPClientBeginOpenROMImage (WindowRef window)
replaceAt = CFStringGetIntValue(numRef); replaceAt = CFStringGetIntValue(numRef);
CFStringReplace(mesRef, CFRangeMake(replaceAt - 1, 1), romRef); CFStringReplace(mesRef, CFRangeMake(replaceAt - 1, 1), romRef);
r = NavBeginOpenROMImageSheet(window, mesRef); // r = NavBeginOpenROMImageSheet(window, mesRef);
CFRelease(mesRef); CFRelease(mesRef);
CFRelease(baseRef); CFRelease(baseRef);
@ -1017,7 +1017,7 @@ static void NPClientEndPlayerListSheet (void)
err = HideSheetWindow(sRef); err = HideSheetWindow(sRef);
} }
static pascal OSStatus NPClientSheetEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) static OSStatus NPClientSheetEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
{ {
if (!npclient.dialogsheet) if (!npclient.dialogsheet)
return (eventNotHandledErr); return (eventNotHandledErr);

View File

@ -15,6 +15,7 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/

View File

@ -15,6 +15,7 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/
@ -25,37 +26,34 @@
void CocoaPlayFreezeDefrostSound (void) void CocoaPlayFreezeDefrostSound (void)
{ {
NSAutoreleasePool *pool;
NSBundle *bundle; NSBundle *bundle;
NSString *path; NSString *path;
NSSound *sound; NSSound *sound;
BOOL r; BOOL r;
pool = [[NSAutoreleasePool alloc] init]; @autoreleasepool
{
bundle = [NSBundle mainBundle]; bundle = [NSBundle mainBundle];
path = [bundle pathForSoundResource: @"freeze_defrost"]; path = [bundle pathForSoundResource: @"freeze_defrost"];
if (path) if (path)
{ {
sound = [[NSSound alloc] initWithContentsOfFile: path byReference: YES]; sound = [[NSSound alloc] initWithContentsOfFile: path byReference: YES];
if (sound) if (sound)
{ {
r = [sound play]; r = [sound play];
[sound release]; }
} }
} }
[pool release];
} }
void CocoaAddStatTextToView (NSView *view, NSString *label, float x, float y, float w, float h, NSTextField **out) void CocoaAddStatTextToView (NSView *view, NSString *label, float x, float y, float w, float h, NSTextField **out)
{ {
NSTextField *control; NSTextField *control;
control = [[[NSTextField alloc] init] autorelease]; control = [[NSTextField alloc] init];
[[control cell] setControlSize: NSSmallControlSize]; [[control cell] setControlSize: NSControlSizeSmall];
[control setFont: [NSFont systemFontOfSize: [NSFont systemFontSizeForControlSize: NSSmallControlSize]]]; [control setFont: [NSFont systemFontOfSize: [NSFont systemFontSizeForControlSize: NSControlSizeSmall]]];
[control setStringValue: NSLocalizedString(label, @"")]; [control setStringValue: NSLocalizedString(label, @"")];
[control setBezeled: NO]; [control setBezeled: NO];
[control setDrawsBackground: NO]; [control setDrawsBackground: NO];
@ -73,10 +71,10 @@ void CocoaAddEditTextToView (NSView *view, NSString *label, float x, float y, fl
{ {
NSTextField *control; NSTextField *control;
control = [[[NSTextField alloc] init] autorelease]; control = [[NSTextField alloc] init];
[[control cell] setControlSize: NSSmallControlSize]; [[control cell] setControlSize: NSControlSizeSmall];
[control setFont: [NSFont systemFontOfSize: [NSFont systemFontSizeForControlSize: NSSmallControlSize]]]; [control setFont: [NSFont systemFontOfSize: [NSFont systemFontSizeForControlSize: NSControlSizeSmall]]];
[control setStringValue: NSLocalizedString(label, @"")]; [control setStringValue: NSLocalizedString(label, @"")];
[control setBezeled: YES]; [control setBezeled: YES];
[control setDrawsBackground: YES]; [control setDrawsBackground: YES];
@ -94,13 +92,13 @@ void CocoaAddMPushBtnToView (NSView *view, NSString *label, float x, float y, fl
{ {
NSButton *control; NSButton *control;
control = [[[NSButton alloc] init] autorelease]; control = [[NSButton alloc] init];
[[control cell] setControlSize: NSSmallControlSize]; [[control cell] setControlSize: NSControlSizeSmall];
[control setFont: [NSFont systemFontOfSize: [NSFont systemFontSizeForControlSize: NSSmallControlSize]]]; [control setFont: [NSFont systemFontOfSize: [NSFont systemFontSizeForControlSize: NSControlSizeSmall]]];
[control setTitle: NSLocalizedString(label, @"")]; [control setTitle: NSLocalizedString(label, @"")];
[control setBezelStyle: NSRoundedBezelStyle]; [control setBezelStyle: NSBezelStyleRounded];
[control setButtonType: NSMomentaryPushInButton]; [control setButtonType: NSButtonTypeMomentaryPushIn];
[view addSubview: control]; [view addSubview: control];
[control setFrame: NSMakeRect(x, y, w, h)]; [control setFrame: NSMakeRect(x, y, w, h)];
@ -113,12 +111,12 @@ void CocoaAddCheckBoxToView (NSView *view, NSString *label, float x, float y, fl
{ {
NSButton *control; NSButton *control;
control = [[[NSButton alloc] init] autorelease]; control = [[NSButton alloc] init];
[[control cell] setControlSize: NSSmallControlSize]; [[control cell] setControlSize: NSControlSizeSmall];
[control setFont: [NSFont systemFontOfSize: [NSFont systemFontSizeForControlSize: NSSmallControlSize]]]; [control setFont: [NSFont systemFontOfSize: [NSFont systemFontSizeForControlSize: NSControlSizeSmall]]];
[control setTitle: NSLocalizedString(label, @"")]; [control setTitle: NSLocalizedString(label, @"")];
[control setButtonType: NSSwitchButton]; [control setButtonType: NSButtonTypeSwitch];
[view addSubview: control]; [view addSubview: control];
[control setFrame: NSMakeRect(x, y, w, h)]; [control setFrame: NSMakeRect(x, y, w, h)];
@ -131,9 +129,9 @@ void CocoaAddPopUpBtnToView (NSView *view, NSArray *array, float x, float y, flo
{ {
NSPopUpButton *control; NSPopUpButton *control;
NSMenu *menu; NSMenu *menu;
int n; NSUInteger n;
menu = [[[NSMenu alloc] init] autorelease]; menu = [[NSMenu alloc] init];
n = [array count]; n = [array count];
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
@ -145,10 +143,10 @@ void CocoaAddPopUpBtnToView (NSView *view, NSArray *array, float x, float y, flo
[menu addItemWithTitle: item action: NULL keyEquivalent: @""]; [menu addItemWithTitle: item action: NULL keyEquivalent: @""];
} }
control = [[[NSPopUpButton alloc] init] autorelease]; control = [[NSPopUpButton alloc] init];
[[control cell] setControlSize: NSSmallControlSize]; [[control cell] setControlSize: NSControlSizeSmall];
[control setFont: [NSFont systemFontOfSize: [NSFont systemFontSizeForControlSize: NSSmallControlSize]]]; [control setFont: [NSFont systemFontOfSize: [NSFont systemFontSizeForControlSize: NSControlSizeSmall]]];
[control setPullsDown: NO]; [control setPullsDown: NO];
[control setMenu: menu]; [control setMenu: menu];

View File

@ -1,312 +0,0 @@
/*****************************************************************************\
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 "port.h"
#include "controls.h"
#include "mac-prefix.h"
#include "mac-joypad.h"
#include "mac-keyboard.h"
#include "mac-os.h"
#include "mac-controls.h"
#define ASSIGN_BUTTONf(n, s) S9xMapButton (n, cmd = S9xGetCommandT(s), false)
#define ASSIGN_BUTTONt(n, s) S9xMapButton (n, cmd = S9xGetCommandT(s), true)
#define ASSIGN_POINTRf(n, s) S9xMapPointer(n, cmd = S9xGetCommandT(s), false)
#define ASSIGN_POINTRt(n, s) S9xMapPointer(n, cmd = S9xGetCommandT(s), true)
#define KeyIsPressed(km, k) (1 & (((unsigned char *) km) [(k) >> 3] >> ((k) & 7)))
void S9xSetupDefaultKeymap (void)
{
s9xcommand_t cmd;
ASSIGN_BUTTONf(kMacCMapPad1PX, "Joypad1 X");
ASSIGN_BUTTONf(kMacCMapPad1PA, "Joypad1 A");
ASSIGN_BUTTONf(kMacCMapPad1PB, "Joypad1 B");
ASSIGN_BUTTONf(kMacCMapPad1PY, "Joypad1 Y");
ASSIGN_BUTTONf(kMacCMapPad1PL, "Joypad1 L");
ASSIGN_BUTTONf(kMacCMapPad1PR, "Joypad1 R");
ASSIGN_BUTTONf(kMacCMapPad1PSelect, "Joypad1 Select");
ASSIGN_BUTTONf(kMacCMapPad1PStart, "Joypad1 Start");
ASSIGN_BUTTONf(kMacCMapPad1PUp, "Joypad1 Up");
ASSIGN_BUTTONf(kMacCMapPad1PDown, "Joypad1 Down");
ASSIGN_BUTTONf(kMacCMapPad1PLeft, "Joypad1 Left");
ASSIGN_BUTTONf(kMacCMapPad1PRight, "Joypad1 Right");
ASSIGN_BUTTONf(kMacCMapPad2PX, "Joypad2 X");
ASSIGN_BUTTONf(kMacCMapPad2PA, "Joypad2 A");
ASSIGN_BUTTONf(kMacCMapPad2PB, "Joypad2 B");
ASSIGN_BUTTONf(kMacCMapPad2PY, "Joypad2 Y");
ASSIGN_BUTTONf(kMacCMapPad2PL, "Joypad2 L");
ASSIGN_BUTTONf(kMacCMapPad2PR, "Joypad2 R");
ASSIGN_BUTTONf(kMacCMapPad2PSelect, "Joypad2 Select");
ASSIGN_BUTTONf(kMacCMapPad2PStart, "Joypad2 Start");
ASSIGN_BUTTONf(kMacCMapPad2PUp, "Joypad2 Up");
ASSIGN_BUTTONf(kMacCMapPad2PDown, "Joypad2 Down");
ASSIGN_BUTTONf(kMacCMapPad2PLeft, "Joypad2 Left");
ASSIGN_BUTTONf(kMacCMapPad2PRight, "Joypad2 Right");
ASSIGN_BUTTONf(kMacCMapPad3PX, "Joypad3 X");
ASSIGN_BUTTONf(kMacCMapPad3PA, "Joypad3 A");
ASSIGN_BUTTONf(kMacCMapPad3PB, "Joypad3 B");
ASSIGN_BUTTONf(kMacCMapPad3PY, "Joypad3 Y");
ASSIGN_BUTTONf(kMacCMapPad3PL, "Joypad3 L");
ASSIGN_BUTTONf(kMacCMapPad3PR, "Joypad3 R");
ASSIGN_BUTTONf(kMacCMapPad3PSelect, "Joypad3 Select");
ASSIGN_BUTTONf(kMacCMapPad3PStart, "Joypad3 Start");
ASSIGN_BUTTONf(kMacCMapPad3PUp, "Joypad3 Up");
ASSIGN_BUTTONf(kMacCMapPad3PDown, "Joypad3 Down");
ASSIGN_BUTTONf(kMacCMapPad3PLeft, "Joypad3 Left");
ASSIGN_BUTTONf(kMacCMapPad3PRight, "Joypad3 Right");
ASSIGN_BUTTONf(kMacCMapPad4PX, "Joypad4 X");
ASSIGN_BUTTONf(kMacCMapPad4PA, "Joypad4 A");
ASSIGN_BUTTONf(kMacCMapPad4PB, "Joypad4 B");
ASSIGN_BUTTONf(kMacCMapPad4PY, "Joypad4 Y");
ASSIGN_BUTTONf(kMacCMapPad4PL, "Joypad4 L");
ASSIGN_BUTTONf(kMacCMapPad4PR, "Joypad4 R");
ASSIGN_BUTTONf(kMacCMapPad4PSelect, "Joypad4 Select");
ASSIGN_BUTTONf(kMacCMapPad4PStart, "Joypad4 Start");
ASSIGN_BUTTONf(kMacCMapPad4PUp, "Joypad4 Up");
ASSIGN_BUTTONf(kMacCMapPad4PDown, "Joypad4 Down");
ASSIGN_BUTTONf(kMacCMapPad4PLeft, "Joypad4 Left");
ASSIGN_BUTTONf(kMacCMapPad4PRight, "Joypad4 Right");
ASSIGN_BUTTONf(kMacCMapPad5PX, "Joypad5 X");
ASSIGN_BUTTONf(kMacCMapPad5PA, "Joypad5 A");
ASSIGN_BUTTONf(kMacCMapPad5PB, "Joypad5 B");
ASSIGN_BUTTONf(kMacCMapPad5PY, "Joypad5 Y");
ASSIGN_BUTTONf(kMacCMapPad5PL, "Joypad5 L");
ASSIGN_BUTTONf(kMacCMapPad5PR, "Joypad5 R");
ASSIGN_BUTTONf(kMacCMapPad5PSelect, "Joypad5 Select");
ASSIGN_BUTTONf(kMacCMapPad5PStart, "Joypad5 Start");
ASSIGN_BUTTONf(kMacCMapPad5PUp, "Joypad5 Up");
ASSIGN_BUTTONf(kMacCMapPad5PDown, "Joypad5 Down");
ASSIGN_BUTTONf(kMacCMapPad5PLeft, "Joypad5 Left");
ASSIGN_BUTTONf(kMacCMapPad5PRight, "Joypad5 Right");
ASSIGN_BUTTONf(kMacCMapPad6PX, "Joypad6 X");
ASSIGN_BUTTONf(kMacCMapPad6PA, "Joypad6 A");
ASSIGN_BUTTONf(kMacCMapPad6PB, "Joypad6 B");
ASSIGN_BUTTONf(kMacCMapPad6PY, "Joypad6 Y");
ASSIGN_BUTTONf(kMacCMapPad6PL, "Joypad6 L");
ASSIGN_BUTTONf(kMacCMapPad6PR, "Joypad6 R");
ASSIGN_BUTTONf(kMacCMapPad6PSelect, "Joypad6 Select");
ASSIGN_BUTTONf(kMacCMapPad6PStart, "Joypad6 Start");
ASSIGN_BUTTONf(kMacCMapPad6PUp, "Joypad6 Up");
ASSIGN_BUTTONf(kMacCMapPad6PDown, "Joypad6 Down");
ASSIGN_BUTTONf(kMacCMapPad6PLeft, "Joypad6 Left");
ASSIGN_BUTTONf(kMacCMapPad6PRight, "Joypad6 Right");
ASSIGN_BUTTONf(kMacCMapPad7PX, "Joypad7 X");
ASSIGN_BUTTONf(kMacCMapPad7PA, "Joypad7 A");
ASSIGN_BUTTONf(kMacCMapPad7PB, "Joypad7 B");
ASSIGN_BUTTONf(kMacCMapPad7PY, "Joypad7 Y");
ASSIGN_BUTTONf(kMacCMapPad7PL, "Joypad7 L");
ASSIGN_BUTTONf(kMacCMapPad7PR, "Joypad7 R");
ASSIGN_BUTTONf(kMacCMapPad7PSelect, "Joypad7 Select");
ASSIGN_BUTTONf(kMacCMapPad7PStart, "Joypad7 Start");
ASSIGN_BUTTONf(kMacCMapPad7PUp, "Joypad7 Up");
ASSIGN_BUTTONf(kMacCMapPad7PDown, "Joypad7 Down");
ASSIGN_BUTTONf(kMacCMapPad7PLeft, "Joypad7 Left");
ASSIGN_BUTTONf(kMacCMapPad7PRight, "Joypad7 Right");
ASSIGN_BUTTONf(kMacCMapPad8PX, "Joypad8 X");
ASSIGN_BUTTONf(kMacCMapPad8PA, "Joypad8 A");
ASSIGN_BUTTONf(kMacCMapPad8PB, "Joypad8 B");
ASSIGN_BUTTONf(kMacCMapPad8PY, "Joypad8 Y");
ASSIGN_BUTTONf(kMacCMapPad8PL, "Joypad8 L");
ASSIGN_BUTTONf(kMacCMapPad8PR, "Joypad8 R");
ASSIGN_BUTTONf(kMacCMapPad8PSelect, "Joypad8 Select");
ASSIGN_BUTTONf(kMacCMapPad8PStart, "Joypad8 Start");
ASSIGN_BUTTONf(kMacCMapPad8PUp, "Joypad8 Up");
ASSIGN_BUTTONf(kMacCMapPad8PDown, "Joypad8 Down");
ASSIGN_BUTTONf(kMacCMapPad8PLeft, "Joypad8 Left");
ASSIGN_BUTTONf(kMacCMapPad8PRight, "Joypad8 Right");
ASSIGN_BUTTONt(kMacCMapMouse1PL, "Mouse1 L");
ASSIGN_BUTTONt(kMacCMapMouse1PR, "Mouse1 R");
ASSIGN_BUTTONt(kMacCMapMouse2PL, "Mouse2 L");
ASSIGN_BUTTONt(kMacCMapMouse2PR, "Mouse2 R");
ASSIGN_BUTTONt(kMacCMapScopeOffscreen, "Superscope AimOffscreen");
ASSIGN_BUTTONt(kMacCMapScopeFire, "Superscope Fire");
ASSIGN_BUTTONt(kMacCMapScopeCursor, "Superscope Cursor");
ASSIGN_BUTTONt(kMacCMapScopeTurbo, "Superscope ToggleTurbo");
ASSIGN_BUTTONt(kMacCMapScopePause, "Superscope Pause");
ASSIGN_BUTTONt(kMacCMapLGun1Offscreen, "Justifier1 AimOffscreen");
ASSIGN_BUTTONt(kMacCMapLGun1Trigger, "Justifier1 Trigger");
ASSIGN_BUTTONt(kMacCMapLGun1Start, "Justifier1 Start");
ASSIGN_BUTTONt(kMacCMapLGun2Offscreen, "Justifier2 AimOffscreen");
ASSIGN_BUTTONt(kMacCMapLGun2Trigger, "Justifier2 Trigger");
ASSIGN_BUTTONt(kMacCMapLGun2Start, "Justifier2 Start");
ASSIGN_POINTRt(kMacCMapMouse1Pointer, "Pointer Mouse1");
ASSIGN_POINTRt(kMacCMapMouse2Pointer, "Pointer Mouse2");
ASSIGN_POINTRt(kMacCMapSuperscopePointer, "Pointer Superscope");
ASSIGN_POINTRt(kMacCMapJustifier1Pointer, "Pointer Justifier1");
ASSIGN_POINTRf(PseudoPointerBase, "Pointer Justifier2");
ASSIGN_BUTTONf(kMacCMapPseudoPtrBase + 0, "ButtonToPointer 1u Med");
ASSIGN_BUTTONf(kMacCMapPseudoPtrBase + 1, "ButtonToPointer 1d Med");
ASSIGN_BUTTONf(kMacCMapPseudoPtrBase + 2, "ButtonToPointer 1l Med");
ASSIGN_BUTTONf(kMacCMapPseudoPtrBase + 3, "ButtonToPointer 1r Med");
}
bool S9xPollButton (uint32 id, bool *pressed)
{
#define kmControlKey 0x3B
KeyMap keys;
GetKeys(keys);
*pressed = false;
if (id & k_MO) // mouse
{
switch (id & 0xFF)
{
case 0: *pressed = ISpKeyIsPressed(kISpMouseL); break;
case 1: *pressed = ISpKeyIsPressed(kISpMouseR);
}
}
else
if (id & k_SS) // superscope
{
switch (id & 0xFF)
{
case 0: *pressed = ISpKeyIsPressed(kISpOffScreen) | KeyIsPressed(keys, keyCode[kKeyOffScreen]); break;
case 2: *pressed = ISpKeyIsPressed(kISpScopeC) | KeyIsPressed(keys, keyCode[kKeyScopeCursor]); break;
case 3: *pressed = ISpKeyIsPressed(kISpScopeT) | KeyIsPressed(keys, keyCode[kKeyScopeTurbo]); break;
case 4: *pressed = ISpKeyIsPressed(kISpScopeP) | KeyIsPressed(keys, keyCode[kKeyScopePause]); break;
case 1: *pressed = ISpKeyIsPressed(kISpMouseL);
}
}
else
if (id & k_LG) // justifier
{
if (id & k_C1)
{
switch (id & 0xFF)
{
case 0: *pressed = ISpKeyIsPressed(kISpOffScreen) | KeyIsPressed(keys, keyCode[kKeyOffScreen]); break;
case 1: *pressed = ISpKeyIsPressed(kISpMouseL); break;
case 2: *pressed = ISpKeyIsPressed(kISpMouseR);
}
}
else
{
switch (id & 0xFF)
{
case 0: *pressed = ISpKeyIsPressed(kISp2PStart) | KeyIsPressed(keys, keyCode[k2PStart]); break;
case 1: *pressed = ISpKeyIsPressed(kISp2PB) | KeyIsPressed(keys, keyCode[k2PB]); break;
case 2: *pressed = ISpKeyIsPressed(kISp2PA) | KeyIsPressed(keys, keyCode[k2PA]);
}
}
}
return (true);
}
bool S9xPollPointer (uint32 id, int16 *x, int16 *y)
{
if (id & k_PT)
{
if ((id & k_MO) && fullscreen)
GetGameScreenPointer(x, y, true);
else
GetGameScreenPointer(x, y, false);
}
else
*x = *y = 0;
return (true);
}
bool S9xPollAxis (uint32 id, int16 *value)
{
return (false);
}
s9xcommand_t S9xGetPortCommandT (const char *name)
{
s9xcommand_t cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.type = S9xBadMapping;
return (cmd);
}
char * S9xGetPortCommandName (s9xcommand_t command)
{
static char str[] = "PortCommand";
return (str);
}
void S9xHandlePortCommand (s9xcommand_t cmd, int16 data1, int16 data2)
{
return;
}
bool8 S9xMapInput (const char *name, s9xcommand_t *cmd)
{
return (true);
}
void ControlPadFlagsToS9xReportButtons (int n, uint32 p)
{
uint32 base = k_HD | k_BT | k_JP | (0x100 << n);
S9xReportButton(base + 0, (p & 0x0040));
S9xReportButton(base + 1, (p & 0x0080));
S9xReportButton(base + 2, (p & 0x8000));
S9xReportButton(base + 3, (p & 0x4000));
S9xReportButton(base + 4, (p & 0x0020));
S9xReportButton(base + 5, (p & 0x0010));
S9xReportButton(base + 6, (p & 0x2000));
S9xReportButton(base + 7, (p & 0x1000));
S9xReportButton(base + 8, (p & 0x0800));
S9xReportButton(base + 9, (p & 0x0400));
S9xReportButton(base + 10, (p & 0x0200));
S9xReportButton(base + 11, (p & 0x0100));
}
void ControlPadFlagsToS9xPseudoPointer (uint32 p)
{
// prevent screwiness caused by trying to move the pointer left+right or up+down
if ((p & 0x0c00) == 0x0c00) p &= ~0x0c00;
if ((p & 0x0300) == 0x0300) p &= ~0x0300;
// checks added to prevent a lack of right/down movement from breaking left/up movement
if (!(p & 0x0400))
S9xReportButton(kMacCMapPseudoPtrBase + 0, (p & 0x0800));
if (!(p & 0x0800))
S9xReportButton(kMacCMapPseudoPtrBase + 1, (p & 0x0400));
if (!(p & 0x0100))
S9xReportButton(kMacCMapPseudoPtrBase + 2, (p & 0x0200));
if (!(p & 0x0200))
S9xReportButton(kMacCMapPseudoPtrBase + 3, (p & 0x0100));
}

View File

@ -15,12 +15,17 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/
#ifndef _mac_controls_h_ #ifndef _mac_controls_h_
#define _mac_controls_h_ #define _mac_controls_h_
#define MAC_MAX_PLAYERS 8
#define KeyIsPressed(km, bm, p, k) (km[p][k] || bm[p][k])
enum enum
{ {
k_HD = 0x80000000, k_HD = 0x80000000,
@ -176,7 +181,66 @@ enum
kMacCMapPseudoPtrBase = k_HD | k_PS | k_LG | k_C2 // for Justifier 2P kMacCMapPseudoPtrBase = k_HD | k_PS | k_LG | k_C2 // for Justifier 2P
}; };
typedef enum
{
kUp,
kDown,
kLeft,
kRight,
kY,
kB,
kX,
kA,
kL,
kR,
kStart,
kSelect,
kKeyFastForward,
kKeyFreeze,
kKeyDefrost,
kKeyScreenshot,
kKeySPC,
kKeyScopeTurbo,
kKeyScopePause,
kKeyScopeCursor,
kKeyOffScreen,
kKeyFunction,
kKeyAlt,
kKeyFFDown,
kKeyFFUp,
kKeyEsc,
kKeyTC,
kKeyMouseLeft,
kKeyMouseRight,
kNumButtons
} S9xButtonCode;
typedef enum {
kISpFastForward,
kISpFreeze,
kISpDefrost,
kISpScreenshot,
kISpSPC,
kISpScopeTurbo,
kISpScopePause,
kISpScopeCursor,
kISpOffScreen,
kISpFunction,
kISpAlt,
kISpFFDown,
kISpFFUp,
kISpEsc,
kISpTC,
kISpMouseLeft,
kISpMouseRight
} ISpKey;
void ControlPadFlagsToS9xReportButtons (int, uint32); void ControlPadFlagsToS9xReportButtons (int, uint32);
void ControlPadFlagsToS9xPseudoPointer (uint32); void ControlPadFlagsToS9xPseudoPointer (uint32);
long ISpKeyIsPressed (bool8 keys[MAC_MAX_PLAYERS][kNumButtons], bool8 gamepadButtons[MAC_MAX_PLAYERS][kNumButtons], ISpKey key);
#endif #endif

507
macosx/mac-controls.mm Normal file
View File

@ -0,0 +1,507 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#include "port.h"
#include "controls.h"
#include "mac-prefix.h"
#include "mac-joypad.h"
#include "mac-keyboard.h"
#include "mac-os.h"
#include "mac-controls.h"
#define ASSIGN_BUTTONf(n, s) S9xMapButton (n, cmd = S9xGetCommandT(s), false)
#define ASSIGN_BUTTONt(n, s) S9xMapButton (n, cmd = S9xGetCommandT(s), true)
#define ASSIGN_POINTRf(n, s) S9xMapPointer(n, cmd = S9xGetCommandT(s), false)
#define ASSIGN_POINTRt(n, s) S9xMapPointer(n, cmd = S9xGetCommandT(s), true)
void S9xSetupDefaultKeymap (void)
{
s9xcommand_t cmd;
ASSIGN_BUTTONf(kMacCMapPad1PX, "Joypad1 X");
ASSIGN_BUTTONf(kMacCMapPad1PA, "Joypad1 A");
ASSIGN_BUTTONf(kMacCMapPad1PB, "Joypad1 B");
ASSIGN_BUTTONf(kMacCMapPad1PY, "Joypad1 Y");
ASSIGN_BUTTONf(kMacCMapPad1PL, "Joypad1 L");
ASSIGN_BUTTONf(kMacCMapPad1PR, "Joypad1 R");
ASSIGN_BUTTONf(kMacCMapPad1PSelect, "Joypad1 Select");
ASSIGN_BUTTONf(kMacCMapPad1PStart, "Joypad1 Start");
ASSIGN_BUTTONf(kMacCMapPad1PUp, "Joypad1 Up");
ASSIGN_BUTTONf(kMacCMapPad1PDown, "Joypad1 Down");
ASSIGN_BUTTONf(kMacCMapPad1PLeft, "Joypad1 Left");
ASSIGN_BUTTONf(kMacCMapPad1PRight, "Joypad1 Right");
ASSIGN_BUTTONf(kMacCMapPad2PX, "Joypad2 X");
ASSIGN_BUTTONf(kMacCMapPad2PA, "Joypad2 A");
ASSIGN_BUTTONf(kMacCMapPad2PB, "Joypad2 B");
ASSIGN_BUTTONf(kMacCMapPad2PY, "Joypad2 Y");
ASSIGN_BUTTONf(kMacCMapPad2PL, "Joypad2 L");
ASSIGN_BUTTONf(kMacCMapPad2PR, "Joypad2 R");
ASSIGN_BUTTONf(kMacCMapPad2PSelect, "Joypad2 Select");
ASSIGN_BUTTONf(kMacCMapPad2PStart, "Joypad2 Start");
ASSIGN_BUTTONf(kMacCMapPad2PUp, "Joypad2 Up");
ASSIGN_BUTTONf(kMacCMapPad2PDown, "Joypad2 Down");
ASSIGN_BUTTONf(kMacCMapPad2PLeft, "Joypad2 Left");
ASSIGN_BUTTONf(kMacCMapPad2PRight, "Joypad2 Right");
ASSIGN_BUTTONf(kMacCMapPad3PX, "Joypad3 X");
ASSIGN_BUTTONf(kMacCMapPad3PA, "Joypad3 A");
ASSIGN_BUTTONf(kMacCMapPad3PB, "Joypad3 B");
ASSIGN_BUTTONf(kMacCMapPad3PY, "Joypad3 Y");
ASSIGN_BUTTONf(kMacCMapPad3PL, "Joypad3 L");
ASSIGN_BUTTONf(kMacCMapPad3PR, "Joypad3 R");
ASSIGN_BUTTONf(kMacCMapPad3PSelect, "Joypad3 Select");
ASSIGN_BUTTONf(kMacCMapPad3PStart, "Joypad3 Start");
ASSIGN_BUTTONf(kMacCMapPad3PUp, "Joypad3 Up");
ASSIGN_BUTTONf(kMacCMapPad3PDown, "Joypad3 Down");
ASSIGN_BUTTONf(kMacCMapPad3PLeft, "Joypad3 Left");
ASSIGN_BUTTONf(kMacCMapPad3PRight, "Joypad3 Right");
ASSIGN_BUTTONf(kMacCMapPad4PX, "Joypad4 X");
ASSIGN_BUTTONf(kMacCMapPad4PA, "Joypad4 A");
ASSIGN_BUTTONf(kMacCMapPad4PB, "Joypad4 B");
ASSIGN_BUTTONf(kMacCMapPad4PY, "Joypad4 Y");
ASSIGN_BUTTONf(kMacCMapPad4PL, "Joypad4 L");
ASSIGN_BUTTONf(kMacCMapPad4PR, "Joypad4 R");
ASSIGN_BUTTONf(kMacCMapPad4PSelect, "Joypad4 Select");
ASSIGN_BUTTONf(kMacCMapPad4PStart, "Joypad4 Start");
ASSIGN_BUTTONf(kMacCMapPad4PUp, "Joypad4 Up");
ASSIGN_BUTTONf(kMacCMapPad4PDown, "Joypad4 Down");
ASSIGN_BUTTONf(kMacCMapPad4PLeft, "Joypad4 Left");
ASSIGN_BUTTONf(kMacCMapPad4PRight, "Joypad4 Right");
ASSIGN_BUTTONf(kMacCMapPad5PX, "Joypad5 X");
ASSIGN_BUTTONf(kMacCMapPad5PA, "Joypad5 A");
ASSIGN_BUTTONf(kMacCMapPad5PB, "Joypad5 B");
ASSIGN_BUTTONf(kMacCMapPad5PY, "Joypad5 Y");
ASSIGN_BUTTONf(kMacCMapPad5PL, "Joypad5 L");
ASSIGN_BUTTONf(kMacCMapPad5PR, "Joypad5 R");
ASSIGN_BUTTONf(kMacCMapPad5PSelect, "Joypad5 Select");
ASSIGN_BUTTONf(kMacCMapPad5PStart, "Joypad5 Start");
ASSIGN_BUTTONf(kMacCMapPad5PUp, "Joypad5 Up");
ASSIGN_BUTTONf(kMacCMapPad5PDown, "Joypad5 Down");
ASSIGN_BUTTONf(kMacCMapPad5PLeft, "Joypad5 Left");
ASSIGN_BUTTONf(kMacCMapPad5PRight, "Joypad5 Right");
ASSIGN_BUTTONf(kMacCMapPad6PX, "Joypad6 X");
ASSIGN_BUTTONf(kMacCMapPad6PA, "Joypad6 A");
ASSIGN_BUTTONf(kMacCMapPad6PB, "Joypad6 B");
ASSIGN_BUTTONf(kMacCMapPad6PY, "Joypad6 Y");
ASSIGN_BUTTONf(kMacCMapPad6PL, "Joypad6 L");
ASSIGN_BUTTONf(kMacCMapPad6PR, "Joypad6 R");
ASSIGN_BUTTONf(kMacCMapPad6PSelect, "Joypad6 Select");
ASSIGN_BUTTONf(kMacCMapPad6PStart, "Joypad6 Start");
ASSIGN_BUTTONf(kMacCMapPad6PUp, "Joypad6 Up");
ASSIGN_BUTTONf(kMacCMapPad6PDown, "Joypad6 Down");
ASSIGN_BUTTONf(kMacCMapPad6PLeft, "Joypad6 Left");
ASSIGN_BUTTONf(kMacCMapPad6PRight, "Joypad6 Right");
ASSIGN_BUTTONf(kMacCMapPad7PX, "Joypad7 X");
ASSIGN_BUTTONf(kMacCMapPad7PA, "Joypad7 A");
ASSIGN_BUTTONf(kMacCMapPad7PB, "Joypad7 B");
ASSIGN_BUTTONf(kMacCMapPad7PY, "Joypad7 Y");
ASSIGN_BUTTONf(kMacCMapPad7PL, "Joypad7 L");
ASSIGN_BUTTONf(kMacCMapPad7PR, "Joypad7 R");
ASSIGN_BUTTONf(kMacCMapPad7PSelect, "Joypad7 Select");
ASSIGN_BUTTONf(kMacCMapPad7PStart, "Joypad7 Start");
ASSIGN_BUTTONf(kMacCMapPad7PUp, "Joypad7 Up");
ASSIGN_BUTTONf(kMacCMapPad7PDown, "Joypad7 Down");
ASSIGN_BUTTONf(kMacCMapPad7PLeft, "Joypad7 Left");
ASSIGN_BUTTONf(kMacCMapPad7PRight, "Joypad7 Right");
ASSIGN_BUTTONf(kMacCMapPad8PX, "Joypad8 X");
ASSIGN_BUTTONf(kMacCMapPad8PA, "Joypad8 A");
ASSIGN_BUTTONf(kMacCMapPad8PB, "Joypad8 B");
ASSIGN_BUTTONf(kMacCMapPad8PY, "Joypad8 Y");
ASSIGN_BUTTONf(kMacCMapPad8PL, "Joypad8 L");
ASSIGN_BUTTONf(kMacCMapPad8PR, "Joypad8 R");
ASSIGN_BUTTONf(kMacCMapPad8PSelect, "Joypad8 Select");
ASSIGN_BUTTONf(kMacCMapPad8PStart, "Joypad8 Start");
ASSIGN_BUTTONf(kMacCMapPad8PUp, "Joypad8 Up");
ASSIGN_BUTTONf(kMacCMapPad8PDown, "Joypad8 Down");
ASSIGN_BUTTONf(kMacCMapPad8PLeft, "Joypad8 Left");
ASSIGN_BUTTONf(kMacCMapPad8PRight, "Joypad8 Right");
ASSIGN_BUTTONt(kMacCMapMouse1PL, "Mouse1 L");
ASSIGN_BUTTONt(kMacCMapMouse1PR, "Mouse1 R");
ASSIGN_BUTTONt(kMacCMapMouse2PL, "Mouse2 L");
ASSIGN_BUTTONt(kMacCMapMouse2PR, "Mouse2 R");
ASSIGN_BUTTONt(kMacCMapScopeOffscreen, "Superscope AimOffscreen");
ASSIGN_BUTTONt(kMacCMapScopeFire, "Superscope Fire");
ASSIGN_BUTTONt(kMacCMapScopeCursor, "Superscope Cursor");
ASSIGN_BUTTONt(kMacCMapScopeTurbo, "Superscope ToggleTurbo");
ASSIGN_BUTTONt(kMacCMapScopePause, "Superscope Pause");
ASSIGN_BUTTONt(kMacCMapLGun1Offscreen, "Justifier1 AimOffscreen");
ASSIGN_BUTTONt(kMacCMapLGun1Trigger, "Justifier1 Trigger");
ASSIGN_BUTTONt(kMacCMapLGun1Start, "Justifier1 Start");
ASSIGN_BUTTONt(kMacCMapLGun2Offscreen, "Justifier2 AimOffscreen");
ASSIGN_BUTTONt(kMacCMapLGun2Trigger, "Justifier2 Trigger");
ASSIGN_BUTTONt(kMacCMapLGun2Start, "Justifier2 Start");
ASSIGN_POINTRt(kMacCMapMouse1Pointer, "Pointer Mouse1");
ASSIGN_POINTRt(kMacCMapMouse2Pointer, "Pointer Mouse2");
ASSIGN_POINTRt(kMacCMapSuperscopePointer, "Pointer Superscope");
ASSIGN_POINTRt(kMacCMapJustifier1Pointer, "Pointer Justifier1");
ASSIGN_POINTRf(PseudoPointerBase, "Pointer Justifier2");
ASSIGN_BUTTONf(kMacCMapPseudoPtrBase + 0, "ButtonToPointer 1u Med");
ASSIGN_BUTTONf(kMacCMapPseudoPtrBase + 1, "ButtonToPointer 1d Med");
ASSIGN_BUTTONf(kMacCMapPseudoPtrBase + 2, "ButtonToPointer 1l Med");
ASSIGN_BUTTONf(kMacCMapPseudoPtrBase + 3, "ButtonToPointer 1r Med");
}
bool S9xPollButton (uint32 id, bool *pressed)
{
#define kmControlKey 0x3B
bool8 keys[MAC_MAX_PLAYERS][kNumButtons];
bool8 gamepadButtons[MAC_MAX_PLAYERS][kNumButtons];
CopyPressedKeys(keys, gamepadButtons);
*pressed = false;
if (id & k_MO) // mouse
{
switch (id & 0xFF)
{
case 0: *pressed = ISpKeyIsPressed(keys, gamepadButtons, kISpMouseLeft); break;
case 1: *pressed = ISpKeyIsPressed(keys, gamepadButtons, kISpMouseRight);
}
}
else
if (id & k_SS) // superscope
{
switch (id & 0xFF)
{
case 0: *pressed = ISpKeyIsPressed(keys, gamepadButtons, kISpOffScreen); break;
case 2: *pressed = ISpKeyIsPressed(keys, gamepadButtons, kISpScopeCursor); break;
case 3: *pressed = ISpKeyIsPressed(keys, gamepadButtons, kISpScopeTurbo); break;
case 4: *pressed = ISpKeyIsPressed(keys, gamepadButtons, kISpScopePause); break;
case 1: *pressed = ISpKeyIsPressed(keys, gamepadButtons, kISpMouseLeft);
}
}
else
if (id & k_LG) // justifier
{
if (id & k_C1)
{
switch (id & 0xFF)
{
case 0: *pressed = ISpKeyIsPressed(keys, gamepadButtons, kISpOffScreen); break;
case 1: *pressed = ISpKeyIsPressed(keys, gamepadButtons, kISpMouseLeft); break;
case 2: *pressed = ISpKeyIsPressed(keys, gamepadButtons, kISpMouseRight);
}
}
else
{
switch (id & 0xFF)
{
case 0: *pressed = KeyIsPressed(keys, gamepadButtons, 1, kStart); break;
case 1: *pressed = KeyIsPressed(keys, gamepadButtons, 1, kB); break;
case 2: *pressed = KeyIsPressed(keys, gamepadButtons, 1, kA);
}
}
}
return (true);
}
bool S9xPollPointer (uint32 id, int16 *x, int16 *y)
{
if (id & k_PT)
{
if ((id & k_MO) && fullscreen)
GetGameScreenPointer(x, y, true);
else
GetGameScreenPointer(x, y, false);
}
else
*x = *y = 0;
return (true);
}
bool S9xPollAxis (uint32 id, int16 *value)
{
return (false);
}
s9xcommand_t S9xGetPortCommandT (const char *name)
{
s9xcommand_t cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.type = S9xBadMapping;
return (cmd);
}
char * S9xGetPortCommandName (s9xcommand_t command)
{
static char str[] = "PortCommand";
return (str);
}
void S9xHandlePortCommand (s9xcommand_t cmd, int16 data1, int16 data2)
{
return;
}
bool8 S9xMapInput (const char *name, s9xcommand_t *cmd)
{
return (true);
}
void ControlPadFlagsToS9xReportButtons (int n, uint32 p)
{
uint32 base = k_HD | k_BT | k_JP | (0x100 << n);
S9xReportButton(base + 0, (p & 0x0040));
S9xReportButton(base + 1, (p & 0x0080));
S9xReportButton(base + 2, (p & 0x8000));
S9xReportButton(base + 3, (p & 0x4000));
S9xReportButton(base + 4, (p & 0x0020));
S9xReportButton(base + 5, (p & 0x0010));
S9xReportButton(base + 6, (p & 0x2000));
S9xReportButton(base + 7, (p & 0x1000));
S9xReportButton(base + 8, (p & 0x0800));
S9xReportButton(base + 9, (p & 0x0400));
S9xReportButton(base + 10, (p & 0x0200));
S9xReportButton(base + 11, (p & 0x0100));
}
void ControlPadFlagsToS9xPseudoPointer (uint32 p)
{
// prevent screwiness caused by trying to move the pointer left+right or up+down
if ((p & 0x0c00) == 0x0c00) p &= ~0x0c00;
if ((p & 0x0300) == 0x0300) p &= ~0x0300;
// checks added to prevent a lack of right/down movement from breaking left/up movement
if (!(p & 0x0400))
S9xReportButton(kMacCMapPseudoPtrBase + 0, (p & 0x0800));
if (!(p & 0x0800))
S9xReportButton(kMacCMapPseudoPtrBase + 1, (p & 0x0400));
if (!(p & 0x0100))
S9xReportButton(kMacCMapPseudoPtrBase + 2, (p & 0x0200));
if (!(p & 0x0200))
S9xReportButton(kMacCMapPseudoPtrBase + 3, (p & 0x0100));
}
long ISpKeyIsPressed (bool8 keys[MAC_MAX_PLAYERS][kNumButtons], bool8 gamepadButtons[MAC_MAX_PLAYERS][kNumButtons], ISpKey key)
{
switch (key)
{
case kISpFastForward:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeyFastForward) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeyFastForward) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeyFastForward) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeyFastForward) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeyFastForward) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeyFastForward) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeyFastForward) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeyFastForward);
case kISpFreeze:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeyFreeze) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeyFreeze) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeyFreeze) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeyFreeze) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeyFreeze) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeyFreeze) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeyFreeze) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeyFreeze);
case kISpDefrost:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeyDefrost) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeyDefrost) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeyDefrost) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeyDefrost) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeyDefrost) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeyDefrost) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeyDefrost) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeyDefrost);
case kISpScreenshot:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeyScreenshot) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeyScreenshot) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeyScreenshot) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeyScreenshot) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeyScreenshot) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeyScreenshot) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeyScreenshot) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeyScreenshot);
case kISpSPC:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeySPC) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeySPC) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeySPC) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeySPC) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeySPC) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeySPC) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeySPC) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeySPC);
case kISpScopeTurbo:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeyScopeTurbo) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeyScopeTurbo) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeyScopeTurbo) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeyScopeTurbo) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeyScopeTurbo) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeyScopeTurbo) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeyScopeTurbo) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeyScopeTurbo);
case kISpScopePause:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeyScopePause) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeyScopePause) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeyScopePause) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeyScopePause) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeyScopePause) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeyScopePause) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeyScopePause) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeyScopePause);
case kISpScopeCursor:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeyScopeCursor) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeyScopeCursor) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeyScopeCursor) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeyScopeCursor) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeyScopeCursor) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeyScopeCursor) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeyScopeCursor) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeyScopeCursor);
case kISpOffScreen:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeyOffScreen) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeyOffScreen) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeyOffScreen) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeyOffScreen) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeyOffScreen) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeyOffScreen) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeyOffScreen) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeyOffScreen);
case kISpFunction:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeyFunction) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeyFunction) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeyFunction) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeyFunction) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeyFunction) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeyFunction) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeyFunction) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeyFunction);
case kISpAlt:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeyAlt) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeyAlt) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeyAlt) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeyAlt) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeyAlt) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeyAlt) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeyAlt) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeyAlt);
case kISpFFDown:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeyFFDown) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeyFFDown) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeyFFDown) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeyFFDown) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeyFFDown) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeyFFDown) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeyFFDown) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeyFFDown);
case kISpFFUp:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeyFFUp) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeyFFUp) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeyFFUp) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeyFFUp) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeyFFUp) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeyFFUp) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeyFFUp) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeyFFUp);
case kISpEsc:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeyEsc) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeyEsc) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeyEsc) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeyEsc) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeyEsc) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeyEsc) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeyEsc) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeyEsc);
case kISpTC:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeyTC) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeyTC) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeyTC) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeyTC) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeyTC) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeyTC) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeyTC) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeyTC);
case kISpMouseLeft:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeyMouseLeft) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeyMouseLeft) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeyMouseLeft) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeyMouseLeft) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeyMouseLeft) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeyMouseLeft) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeyMouseLeft) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeyMouseLeft);
case kISpMouseRight:
return
KeyIsPressed(keys, gamepadButtons, 0, kKeyMouseRight) ||
KeyIsPressed(keys, gamepadButtons, 1, kKeyMouseRight) ||
KeyIsPressed(keys, gamepadButtons, 2, kKeyMouseRight) ||
KeyIsPressed(keys, gamepadButtons, 3, kKeyMouseRight) ||
KeyIsPressed(keys, gamepadButtons, 4, kKeyMouseRight) ||
KeyIsPressed(keys, gamepadButtons, 5, kKeyMouseRight) ||
KeyIsPressed(keys, gamepadButtons, 6, kKeyMouseRight) ||
KeyIsPressed(keys, gamepadButtons, 7, kKeyMouseRight);
default:
break;
}
}

View File

@ -15,6 +15,7 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@ -25,8 +25,8 @@ enum
{ {
kS9xMacAlertFolderNotFound = 1, kS9xMacAlertFolderNotFound = 1,
kS9xMacAlertFolderNotFoundHint, kS9xMacAlertFolderNotFoundHint,
kS9xMacAlertFolderFailToCreate, kS9xMacAlertFolderNotWritable,
kS9xMacAlertFolderFailToCreateHint, kS9xMacAlertFolderNotWritableHint,
kS9xMacAlertkBadRom, kS9xMacAlertkBadRom,
kS9xMacAlertkBadRomHint, kS9xMacAlertkBadRomHint,
kS9xMacAlertCFCantAddEntry, kS9xMacAlertCFCantAddEntry,
@ -55,6 +55,6 @@ OSStatus SetEditTextCStr (HIViewRef, char *, Boolean);
OSStatus CopyEditTextCFString (HIViewRef, CFStringRef *); OSStatus CopyEditTextCFString (HIViewRef, CFStringRef *);
OSStatus SetEditTextCFString (HIViewRef, CFStringRef, Boolean); OSStatus SetEditTextCFString (HIViewRef, CFStringRef, Boolean);
OSStatus SetEditTextSelection (HIViewRef, SInt16, SInt16); OSStatus SetEditTextSelection (HIViewRef, SInt16, SInt16);
pascal OSStatus DefaultEventHandler (EventHandlerCallRef, EventRef, void *); OSStatus DefaultEventHandler (EventHandlerCallRef, EventRef, void *);
#endif #endif

View File

@ -44,10 +44,10 @@ static void AutofireWriteAllSettings (int, HIViewRef);
static void AutofireWriteSetting (int, uint16 *, HIViewRef); static void AutofireWriteSetting (int, uint16 *, HIViewRef);
static void AutofireSelectTabPane (HIViewRef, SInt16); static void AutofireSelectTabPane (HIViewRef, SInt16);
static OSStatus UpdateTextControlView (HIViewRef); static OSStatus UpdateTextControlView (HIViewRef);
static pascal void AutofireSliderActionProc (HIViewRef, HIViewPartCode); static void AutofireSliderActionProc (HIViewRef, HIViewPartCode);
static pascal OSStatus RomInfoEventHandler (EventHandlerCallRef, EventRef, void *); static OSStatus RomInfoEventHandler (EventHandlerCallRef, EventRef, void *);
static pascal OSStatus AutofireTabEventHandler (EventHandlerCallRef, EventRef, void *); static OSStatus AutofireTabEventHandler (EventHandlerCallRef, EventRef, void *);
static pascal OSStatus AutofireWindowEventHandler (EventHandlerCallRef, EventRef, void *); static OSStatus AutofireWindowEventHandler (EventHandlerCallRef, EventRef, void *);
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
extern "C" FMFont FMGetFontFromATSFontRef (ATSFontRef iFont); extern "C" FMFont FMGetFontFromATSFontRef (ATSFontRef iFont);
@ -253,7 +253,7 @@ void AppearanceAlert (AlertType type, int stringID1, int stringID2)
if (key1) mes1 = CFCopyLocalizedString(key1, "mes1"); else mes1 = NULL; if (key1) mes1 = CFCopyLocalizedString(key1, "mes1"); else mes1 = NULL;
if (key2) mes2 = CFCopyLocalizedString(key2, "mes2"); else mes2 = NULL; if (key2) mes2 = CFCopyLocalizedString(key2, "mes2"); else mes2 = NULL;
PlayAlertSound(); NSBeep();
err = CreateStandardAlert(type, mes1, mes2, NULL, &dialog); err = CreateStandardAlert(type, mes1, mes2, NULL, &dialog);
err = RunStandardAlert(dialog, NULL, &outItemHit); err = RunStandardAlert(dialog, NULL, &outItemHit);
@ -333,7 +333,7 @@ void AboutDialog (void)
} }
} }
pascal OSStatus DefaultEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) OSStatus DefaultEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
{ {
OSStatus err, result = eventNotHandledErr; OSStatus err, result = eventNotHandledErr;
WindowRef tWindowRef = (WindowRef) inUserData; WindowRef tWindowRef = (WindowRef) inUserData;
@ -787,7 +787,7 @@ static void AutofireSelectTabPane (HIViewRef tabControl, SInt16 index)
HIViewSetNeedsDisplay(tabControl, true); HIViewSetNeedsDisplay(tabControl, true);
} }
static pascal OSStatus AutofireTabEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) static OSStatus AutofireTabEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
{ {
OSStatus err, result = eventNotHandledErr; OSStatus err, result = eventNotHandledErr;
HIViewRef ctl; HIViewRef ctl;
@ -810,7 +810,7 @@ static pascal OSStatus AutofireTabEventHandler (EventHandlerCallRef inHandlerRef
return (result); return (result);
} }
static pascal OSStatus AutofireWindowEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) static OSStatus AutofireWindowEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
{ {
OSStatus err, result = eventNotHandledErr; OSStatus err, result = eventNotHandledErr;
WindowRef tWindowRef = (WindowRef) inUserData; WindowRef tWindowRef = (WindowRef) inUserData;
@ -880,7 +880,7 @@ static pascal OSStatus AutofireWindowEventHandler (EventHandlerCallRef inHandler
return (result); return (result);
} }
static pascal void AutofireSliderActionProc (HIViewRef slider, HIViewPartCode partCode) static void AutofireSliderActionProc (HIViewRef slider, HIViewPartCode partCode)
{ {
HIViewRef ctl; HIViewRef ctl;
HIViewID cid; HIViewID cid;
@ -1081,7 +1081,7 @@ static void RomInfoBuildInfoText (char *romtext)
sprintf(romtext, "%s%s", s1, s2); sprintf(romtext, "%s%s", s1, s2);
} }
static pascal OSStatus RomInfoEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) static OSStatus RomInfoEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
{ {
OSStatus err, result = eventNotHandledErr; OSStatus err, result = eventNotHandledErr;
WindowRef tWindowRef = (WindowRef) inUserData; WindowRef tWindowRef = (WindowRef) inUserData;

View File

@ -1,619 +0,0 @@
/*****************************************************************************\
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 "movie.h"
#include "display.h"
#include <libgen.h>
#include "mac-prefix.h"
#include "mac-dialog.h"
#include "mac-os.h"
#include "mac-stringtools.h"
#include "mac-file.h"
static void AddFolderIcon (FSRef *, const char *);
static OSStatus FindSNESFolder (FSRef *, char *, const char *);
static OSStatus FindApplicationSupportFolder (FSRef *, char *, const char *);
static OSStatus FindCustomFolder (FSRef *, char *, const char *);
void CheckSaveFolder (FSRef *cartRef)
{
OSStatus err;
Boolean r;
FSCatalogInfo finfo;
FSVolumeInfo vinfo;
FSRef ref;
CFURLRef burl, purl;
char s[PATH_MAX + 1];
switch (saveInROMFolder)
{
case 0: // Snes9x folder
burl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
purl = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, burl);
r = CFURLGetFSRef(purl, &ref);
CFRelease(purl);
CFRelease(burl);
break;
case 1: // ROM folder
err = FSGetCatalogInfo(cartRef, kFSCatInfoNone, NULL, NULL, NULL, &ref);
break;
case 2: // Application Support folder
return;
case 4: // Custom folder
if (saveFolderPath == NULL)
{
saveInROMFolder = 2;
return;
}
r = CFStringGetCString(saveFolderPath, s, PATH_MAX, kCFStringEncodingUTF8);
err = FSPathMakeRef((unsigned char *) s, &ref, NULL);
if (err)
{
AppearanceAlert(kAlertCautionAlert, kS9xMacAlertFolderNotFound, kS9xMacAlertFolderNotFoundHint);
saveInROMFolder = 2;
return;
}
break;
}
err = FSGetCatalogInfo(&ref, kFSCatInfoUserPrivs | kFSCatInfoVolume, &finfo, NULL, NULL, NULL);
if (err == noErr)
{
if (finfo.userPrivileges & kioACUserNoMakeChangesMask)
{
AppearanceAlert(kAlertCautionAlert, kS9xMacAlertFolderFailToCreate, kS9xMacAlertFolderFailToCreateHint);
saveInROMFolder = 2;
return;
}
err = FSGetVolumeInfo(finfo.volume, 0, NULL, kFSVolInfoFlags, &vinfo, NULL, NULL);
if (err == noErr)
{
if ((vinfo.flags & kFSVolFlagHardwareLockedMask) || (vinfo.flags & kFSVolFlagSoftwareLockedMask))
{
AppearanceAlert(kAlertCautionAlert, kS9xMacAlertFolderFailToCreate, kS9xMacAlertFolderFailToCreateHint);
saveInROMFolder = 2;
return;
}
}
}
if (err)
saveInROMFolder = 2;
}
static OSStatus FindSNESFolder (FSRef *folderRef, char *folderPath, const char *folderName)
{
OSStatus err;
CFURLRef burl, purl;
CFStringRef fstr;
FSRef pref;
UniChar buffer[PATH_MAX + 1];
Boolean r;
fstr = CFStringCreateWithCString(kCFAllocatorDefault, folderName, CFStringGetSystemEncoding());
CFStringGetCharacters(fstr, CFRangeMake(0, CFStringGetLength(fstr)), buffer);
burl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
purl = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, burl);
r = CFURLGetFSRef(purl, &pref);
err = FSMakeFSRefUnicode(&pref, CFStringGetLength(fstr), buffer, kTextEncodingUnicodeDefault, folderRef);
if (err == dirNFErr || err == fnfErr)
{
err = FSCreateDirectoryUnicode(&pref, CFStringGetLength(fstr), buffer, kFSCatInfoNone, NULL, folderRef, NULL, NULL);
if (err == noErr)
AddFolderIcon(folderRef, folderName);
}
if (err == noErr)
err = FSRefMakePath(folderRef, (unsigned char *) folderPath, PATH_MAX);
CFRelease(purl);
CFRelease(burl);
CFRelease(fstr);
return (err);
}
static OSStatus FindApplicationSupportFolder (FSRef *folderRef, char *folderPath, const char *folderName)
{
OSStatus err;
FSRef p2ref, p1ref;
CFStringRef fstr;
UniChar buffer[PATH_MAX + 1];
UniChar s9xfolder[6] = { 'S', 'n', 'e', 's', '9', 'x' },
oldfolder[6] = { 'S', 'N', 'E', 'S', '9', 'X' };
err = FSFindFolder(kUserDomain, kApplicationSupportFolderType, kCreateFolder, &p2ref);
if (err)
return (err);
err = FSMakeFSRefUnicode(&p2ref, 6, s9xfolder, kTextEncodingUnicodeDefault, &p1ref);
if (err == dirNFErr || err == fnfErr)
{
err = FSMakeFSRefUnicode(&p2ref, 6, oldfolder, kTextEncodingUnicodeDefault, &p1ref);
if (err == dirNFErr || err == fnfErr)
err = FSCreateDirectoryUnicode(&p2ref, 6, s9xfolder, kFSCatInfoNone, NULL, &p1ref, NULL, NULL);
}
if (err)
return (err);
fstr = CFStringCreateWithCString(kCFAllocatorDefault, folderName, CFStringGetSystemEncoding());
CFStringGetCharacters(fstr, CFRangeMake(0, CFStringGetLength(fstr)), buffer);
err = FSMakeFSRefUnicode(&p1ref, CFStringGetLength(fstr), buffer, kTextEncodingUnicodeDefault, folderRef);
if (err == dirNFErr || err == fnfErr)
{
err = FSCreateDirectoryUnicode(&p1ref, CFStringGetLength(fstr), buffer, kFSCatInfoNone, NULL, folderRef, NULL, NULL);
if (err == noErr)
AddFolderIcon(folderRef, folderName);
}
if (err == noErr)
err = FSRefMakePath(folderRef, (unsigned char *) folderPath, PATH_MAX);
CFRelease(fstr);
return (err);
}
static OSStatus FindCustomFolder (FSRef *folderRef, char *folderPath, const char *folderName)
{
OSStatus err;
CFStringRef fstr;
FSRef pref;
UniChar buffer[PATH_MAX + 1];
char s[PATH_MAX + 1];
if (saveFolderPath == NULL)
return (-1);
err = CFStringGetCString(saveFolderPath, s, PATH_MAX, kCFStringEncodingUTF8) ? noErr : -1;
if (err == noErr)
err = FSPathMakeRef((unsigned char *) s, &pref, NULL);
if (err)
return (err);
fstr = CFStringCreateWithCString(kCFAllocatorDefault, folderName, CFStringGetSystemEncoding());
CFStringGetCharacters(fstr, CFRangeMake(0, CFStringGetLength(fstr)), buffer);
err = FSMakeFSRefUnicode(&pref, CFStringGetLength(fstr), buffer, kTextEncodingUnicodeDefault, folderRef);
if (err == dirNFErr || err == fnfErr)
{
err = FSCreateDirectoryUnicode(&pref, CFStringGetLength(fstr), buffer, kFSCatInfoNone, NULL, folderRef, NULL, NULL);
if (err == noErr)
AddFolderIcon(folderRef, folderName);
}
if (err == noErr)
err = FSRefMakePath(folderRef, (unsigned char *) folderPath, PATH_MAX);
CFRelease(fstr);
return (err);
}
void ChangeTypeAndCreator (const char *path, OSType type, OSType creator)
{
OSStatus err;
FSRef ref;
err = FSPathMakeRef((unsigned char *) path, &ref, NULL);
if (err == noErr)
{
FSCatalogInfo catinfo;
err = FSGetCatalogInfo(&ref, kFSCatInfoFinderInfo, &catinfo, NULL, NULL, NULL);
if (err == noErr)
{
((FileInfo *) &catinfo.finderInfo)->fileCreator = creator;
((FileInfo *) &catinfo.finderInfo)->fileType = type;
err = FSSetCatalogInfo(&ref, kFSCatInfoFinderInfo, &catinfo);
}
}
}
static void AddFolderIcon (FSRef *fref, const char *folderName)
{
OSStatus err;
FSCatalogInfo fcat, icat;
FSRef bref, iref;
CFStringRef str;
CFURLRef url;
IconFamilyHandle family;
IconRef icon;
HFSUniStr255 fork;
Boolean r;
SInt16 resf;
char name[64];
UniChar iconName[5] = { 'I', 'c', 'o', 'n', '\r' };
strcpy(name, "folder_");
strcat(name, folderName);
str = CFStringCreateWithCString(kCFAllocatorDefault, name, CFStringGetSystemEncoding());
if (str)
{
url = CFBundleCopyResourceURL(CFBundleGetMainBundle(), str, CFSTR("icns"), NULL);
if (url)
{
r = CFURLGetFSRef(url, &bref);
if (r)
{
err = RegisterIconRefFromFSRef('~9X~', 'TEMP', &bref, &icon);
if (err == noErr)
{
err = FSGetResourceForkName(&fork);
if (err == noErr)
{
err = FSCreateResourceFile(fref, 5, iconName, kFSCatInfoNone, NULL, fork.length, fork.unicode, &iref, NULL);
if (err == noErr)
{
err = FSOpenResourceFile(&iref, fork.length, fork.unicode, fsWrPerm, &resf);
if (err == noErr)
{
err = IconRefToIconFamily(icon, kSelectorAllAvailableData, &family);
if (err == noErr)
{
AddResource((Handle) family, 'icns', -16455, "\p");
WriteResource((Handle) family);
ReleaseResource((Handle) family);
err = FSGetCatalogInfo(&iref, kFSCatInfoFinderInfo, &icat, NULL, NULL, NULL);
((FileInfo *) &icat.finderInfo)->finderFlags |= kIsInvisible;
((FileInfo *) &icat.finderInfo)->fileCreator = 'MACS';
((FileInfo *) &icat.finderInfo)->fileType = 'icon';
err = FSSetCatalogInfo(&iref, kFSCatInfoFinderInfo, &icat);
err = FSGetCatalogInfo(fref, kFSCatInfoFinderInfo, &fcat, NULL, NULL, NULL);
((FolderInfo *) &fcat.finderInfo)->finderFlags |= kHasCustomIcon;
((FolderInfo *) &fcat.finderInfo)->finderFlags &= ~kHasBeenInited;
err = FSSetCatalogInfo(fref, kFSCatInfoFinderInfo, &fcat);
}
CloseResFile(resf);
}
}
}
err = UnregisterIconRef('~9X~', 'TEMP');
}
}
CFRelease(url);
}
CFRelease(str);
}
}
const char * S9xGetFilename (const char *inExt, enum s9x_getdirtype dirtype)
{
static int index = 0;
static char filePath[4][PATH_MAX + 1];
OSStatus err;
FSRef ref;
uint32 type;
char folderName[16];
char drive[_MAX_DRIVE + 1], dir[_MAX_DIR + 1], fname[_MAX_FNAME + 1], ext[_MAX_EXT + 1];
const char *p;
index++;
if (index > 3)
index = 0;
folderName[0] = filePath[index][0] = 0;
if (strlen(inExt) < 4)
return (filePath[index]);
p = inExt + strlen(inExt) - 4;
type = ((uint32) p[0] << 24) + ((uint32) p[1] << 16) + ((uint32) p[2] << 8) + (uint32) p[3];
switch (type)
{
case '.srm':
case '.rtc':
strcpy(folderName, "SRAMs");
break;
case '.frz':
strcpy(folderName, "Freezes");
break;
case '.spc':
strcpy(folderName, "SPCs");
break;
case '.cht':
strcpy(folderName, "Cheats");
break;
case '.ups':
case '.ips':
strcpy(folderName, "Patches");
break;
case '.png':
strcpy(folderName, "Screenshots");
break;
case '.dat':
case '.out':
case '.log':
strcpy(folderName, "Logs");
break;
case '.bio': // dummy
strcpy(folderName, "BIOSes");
break;
}
if (folderName[0] && (saveInROMFolder != 1))
{
char s[PATH_MAX + 1];
s[0] = 0;
err = -1;
if (saveInROMFolder == 0)
{
err = FindSNESFolder(&ref, s, folderName);
if (err)
saveInROMFolder = 2;
}
if (saveInROMFolder == 4)
{
err = FindCustomFolder(&ref, s, folderName);
if (err)
saveInROMFolder = 2;
}
if (saveInROMFolder == 2)
err = FindApplicationSupportFolder(&ref, s, folderName);
if (err == noErr)
{
_splitpath(Memory.ROMFilename, drive, dir, fname, ext);
snprintf(filePath[index], PATH_MAX + 1, "%s%s%s%s", s, MAC_PATH_SEPARATOR, fname, inExt);
}
else
{
_splitpath(Memory.ROMFilename, drive, dir, fname, ext);
_makepath(filePath[index], drive, dir, fname, inExt);
}
}
else
{
_splitpath(Memory.ROMFilename, drive, dir, fname, ext);
_makepath(filePath[index], drive, dir, fname, inExt);
}
return (filePath[index]);
}
const char * S9xGetSPCFilename (void)
{
char spcExt[16];
sprintf(spcExt, ".%03d.spc", (int) spcFileCount);
spcFileCount++;
if (spcFileCount == 1000)
spcFileCount = 0;
return (S9xGetFilename(spcExt, SPC_DIR));
}
const char * S9xGetPNGFilename (void)
{
char pngExt[16];
sprintf(pngExt, ".%03d.png", (int) pngFileCount);
pngFileCount++;
if (pngFileCount == 1000)
pngFileCount = 0;
return (S9xGetFilename(pngExt, SCREENSHOT_DIR));
}
const char * S9xGetFreezeFilename (int which)
{
char frzExt[16];
sprintf(frzExt, ".%03d.frz", which);
return (S9xGetFilename(frzExt, SNAPSHOT_DIR));
}
const char * S9xGetFilenameInc (const char *inExt, enum s9x_getdirtype dirtype)
{
uint32 type;
const char *p;
if (strlen(inExt) < 4)
return (NULL);
p = inExt + strlen(inExt) - 4;
type = ((uint32) p[0] << 24) + ((uint32) p[1] << 16) + ((uint32) p[2] << 8) + (uint32) p[3];
switch (type)
{
case '.spc':
return (S9xGetSPCFilename());
case '.png':
return (S9xGetPNGFilename());
}
return (NULL);
}
const char * S9xChooseFilename (bool8 read_only)
{
return (NULL);
}
const char * S9xChooseMovieFilename (bool8 read_only)
{
return (NULL);
}
bool8 S9xOpenSnapshotFile (const char *fname, bool8 read_only, STREAM *file)
{
if (read_only)
{
if (0 != (*file = OPEN_STREAM(fname, "rb")))
return (true);
}
else
{
if (0 != (*file = OPEN_STREAM(fname, "wb")))
return (true);
}
return (false);
}
void S9xCloseSnapshotFile (STREAM file)
{
CLOSE_STREAM(file);
}
const char * S9xBasename (const char *in)
{
static char s[PATH_MAX + 1];
strncpy(s, in, PATH_MAX + 1);
s[PATH_MAX] = 0;
size_t l = strlen(s);
for (unsigned int i = 0; i < l; i++)
{
if (s[i] < 32 || s[i] >= 127)
s[i] = '_';
}
return (basename(s));
}
const char * S9xGetDirectory (enum s9x_getdirtype dirtype)
{
static int index = 0;
static char path[4][PATH_MAX + 1];
char inExt[16];
char drive[_MAX_DRIVE + 1], dir[_MAX_DIR + 1], fname[_MAX_FNAME + 1], ext[_MAX_EXT + 1];
index++;
if (index > 3)
index = 0;
switch (dirtype)
{
case SNAPSHOT_DIR: strcpy(inExt, ".frz"); break;
case SRAM_DIR: strcpy(inExt, ".srm"); break;
case SCREENSHOT_DIR: strcpy(inExt, ".png"); break;
case SPC_DIR: strcpy(inExt, ".spc"); break;
case CHEAT_DIR: strcpy(inExt, ".cht"); break;
case BIOS_DIR: strcpy(inExt, ".bio"); break;
case LOG_DIR: strcpy(inExt, ".log"); break;
default: strcpy(inExt, ".xxx"); break;
}
_splitpath(S9xGetFilename(inExt, dirtype), drive, dir, fname, ext);
_makepath(path[index], drive, dir, "", "");
int l = strlen(path[index]);
if (l > 1)
path[index][l - 1] = 0;
return (path[index]);
}
void _splitpath (const char *path, char *drive, char *dir, char *fname, char *ext)
{
drive[0] = 0;
fname[0] = 0;
ext[0] = 0;
dir[0] = 0;
int x;
x = strlen(path) - 1;
if (x < 0)
return;
while (x && (path[x] != MAC_PATH_SEP_CHAR))
x--;
if (x)
{
strcpy(dir, path);
dir[x + 1] = 0;
strcpy(fname, path + x + 1);
}
else
strcpy(fname, path);
x = strlen(fname);
while (x && (fname[x] != '.'))
x--;
if (x)
{
strcpy(ext, fname + x);
fname[x] = 0;
}
}
void _makepath (char *path, const char *drive, const char *dir, const char *fname, const char *ext)
{
static const char emp[] = "", dot[] = ".";
const char *d, *f, *e, *p;
d = dir ? dir : emp;
f = fname ? fname : emp;
e = ext ? ext : emp;
p = (e[0] && e[0] != '.') ? dot : emp;
snprintf(path, PATH_MAX + 1, "%s%s%s%s", d, f, p, e);
}

View File

@ -15,13 +15,14 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/
#ifndef _mac_file_h_ #ifndef _mac_file_h_
#define _mac_file_h_ #define _mac_file_h_
void CheckSaveFolder (FSRef *); void CheckSaveFolder (NSURL *);
void ChangeTypeAndCreator (const char *, OSType, OSType); void ChangeTypeAndCreator (const char *, OSType, OSType);
const char * S9xGetSPCFilename (void); const char * S9xGetSPCFilename (void);
const char * S9xGetPNGFilename (void); const char * S9xGetPNGFilename (void);

500
macosx/mac-file.mm Normal file
View File

@ -0,0 +1,500 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#import <Cocoa/Cocoa.h>
#include "snes9x.h"
#include "memmap.h"
#include "movie.h"
#include "display.h"
#include <libgen.h>
#include "mac-prefix.h"
#include "mac-dialog.h"
#include "mac-os.h"
#include "mac-stringtools.h"
#include "mac-file.h"
static void AddFolderIcon (NSURL *, const char *);
static NSURL *FindSNESFolder (const char *);
static NSURL *FindApplicationSupportFolder (NSURL *, const char *);
static NSURL *FindCustomFolder (NSURL *, const char *);
void CheckSaveFolder (NSURL *cartURL)
{
NSString *folderPath = nil;
switch (saveInROMFolder)
{
case 1: // ROM folder
folderPath = cartURL.URLByDeletingLastPathComponent.path;
break;
case 2: // Application Support folder
return;
case 4: // Custom folder
if (saveFolderPath == NULL)
{
saveInROMFolder = 2;
return;
}
BOOL isDirectory = NO;
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:saveFolderPath isDirectory:&isDirectory];
if (exists && isDirectory)
{
folderPath = saveFolderPath;
}
else
{
//AppearanceAlert(kAlertCautionAlert, kS9xMacAlertFolderNotFound, kS9xMacAlertFolderNotFoundHint);
saveInROMFolder = 2;
return;
}
break;
}
BOOL writable = [[NSFileManager defaultManager] isWritableFileAtPath:folderPath];
if (!writable)
{
//AppearanceAlert(kAlertCautionAlert, kS9xMacAlertFolderNotWritable, kS9xMacAlertFolderNotWritableHint);
saveInROMFolder = 2;
return;
}
}
static NSURL *FindSNESFolder (const char *folderName)
{
NSURL *purl = nil;
NSString *fstr = [NSString stringWithUTF8String:folderName];
purl = [[[NSBundle mainBundle] bundleURL].URLByDeletingLastPathComponent URLByAppendingPathComponent:fstr];
if (![NSFileManager.defaultManager fileExistsAtPath:purl.path])
{
NSError *error = nil;
if ( [NSFileManager.defaultManager createDirectoryAtURL:purl withIntermediateDirectories:YES attributes:nil error:&error] )
{
AddFolderIcon(purl, folderName);
}
else
{
[[NSAlert alertWithError:error] runModal];
}
}
return purl;
}
static NSURL *FindApplicationSupportFolder (const char *folderName)
{
NSURL *purl = nil;
NSURL *baseURL = nil;
NSURL *s9xURL = nil;
NSURL *oldURL = nil;
NSString *fstr = [NSString stringWithUTF8String:folderName];
baseURL = [NSFileManager.defaultManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask].firstObject;
if (!baseURL)
{
return nil;
}
s9xURL = [baseURL URLByAppendingPathComponent:@"Snes9x"];
oldURL = [baseURL URLByAppendingPathComponent:@"SNES9X"];
if ([NSFileManager.defaultManager fileExistsAtPath:s9xURL.path])
{
purl = [s9xURL URLByAppendingPathComponent:fstr];
}
else if ([NSFileManager.defaultManager fileExistsAtPath:oldURL.path])
{
purl = [oldURL URLByAppendingPathComponent:fstr];
}
if (purl == NULL)
{
purl = [s9xURL URLByAppendingPathComponent:fstr];
}
[NSFileManager.defaultManager createDirectoryAtURL:purl withIntermediateDirectories:YES attributes:nil error:NULL];
return purl;
}
static NSURL *FindCustomFolder (const char *folderName)
{
NSURL *purl = nil;
if (saveFolderPath == NULL)
return nil;
purl = [NSURL fileURLWithPath:saveFolderPath];
if (![NSFileManager.defaultManager fileExistsAtPath:saveFolderPath])
{
NSError *error = nil;
if (![NSFileManager.defaultManager createDirectoryAtPath:saveFolderPath withIntermediateDirectories:YES attributes:nil error:&error])
{
[[NSAlert alertWithError:error] runModal];
return nil;
}
}
purl = [purl URLByAppendingPathComponent:[NSString stringWithUTF8String:folderName]];
if (![NSFileManager.defaultManager fileExistsAtPath:purl.path])
{
NSError *error = nil;
if ([NSFileManager.defaultManager createDirectoryAtPath:saveFolderPath withIntermediateDirectories:YES attributes:nil error:&error])
{
AddFolderIcon(purl, folderName);
}
{
[[NSAlert alertWithError:error] runModal];
return nil;
}
}
return purl;
}
void ChangeTypeAndCreator (const char *path, OSType type, OSType creator)
{
// NSError *error = nil;
// if (![NSFileManager.defaultManager setAttributes:@{NSFileHFSCreatorCode: @(creator), NSFileHFSTypeCode: @(type)} ofItemAtPath:[NSString stringWithUTF8String:path] error:&error])
// {
// [[NSAlert alertWithError:error] runModal];
// }
}
static void AddFolderIcon (NSURL *fref, const char *folderName)
{
NSBundle *bundle = [NSBundle mainBundle];
NSString *filename = [@"folder_" stringByAppendingString:[NSString stringWithUTF8String:folderName]];
NSURL *imageURL = [bundle URLForResource:filename withExtension:@"icns"];
NSImage *image = [[NSImage alloc] initWithContentsOfURL:imageURL];
if ( image != nil )
{
[NSWorkspace.sharedWorkspace setIcon:image forFile:fref.path options:0];
}
}
const char * S9xGetFilename (const char *inExt, enum s9x_getdirtype dirtype)
{
static int index = 0;
static char filePath[4][PATH_MAX + 1];
uint32 type;
char folderName[16];
char drive[_MAX_DRIVE + 1], dir[_MAX_DIR + 1], fname[_MAX_FNAME + 1], ext[_MAX_EXT + 1];
const char *p;
index++;
if (index > 3)
index = 0;
folderName[0] = filePath[index][0] = 0;
if (strlen(inExt) < 4)
return (filePath[index]);
p = inExt + strlen(inExt) - 4;
type = ((uint32) p[0] << 24) + ((uint32) p[1] << 16) + ((uint32) p[2] << 8) + (uint32) p[3];
switch (type)
{
case '.srm':
case '.rtc':
strcpy(folderName, "SRAMs");
break;
case '.frz':
strcpy(folderName, "Freezes");
break;
case '.spc':
strcpy(folderName, "SPCs");
break;
case '.cht':
strcpy(folderName, "Cheats");
break;
case '.ups':
case '.ips':
strcpy(folderName, "Patches");
break;
case '.png':
strcpy(folderName, "Screenshots");
break;
case '.dat':
case '.out':
case '.log':
strcpy(folderName, "Logs");
break;
case '.bio': // dummy
strcpy(folderName, "BIOSes");
break;
}
if (folderName[0] && (saveInROMFolder != 1))
{
NSURL *folderURL = nil;
if (saveInROMFolder == 0)
{
folderURL = FindSNESFolder(folderName);
if (folderURL == nil)
saveInROMFolder = 2;
}
if (saveInROMFolder == 4)
{
folderURL = FindCustomFolder(folderName);
if (folderURL == nil)
saveInROMFolder = 2;
}
if (saveInROMFolder == 2)
folderURL = FindApplicationSupportFolder(folderName);
if (folderURL != nil)
{
_splitpath(Memory.ROMFilename, drive, dir, fname, ext);
snprintf(filePath[index], PATH_MAX + 1, "%s%s%s%s", folderURL.path.UTF8String, MAC_PATH_SEPARATOR, fname, inExt);
}
else
{
_splitpath(Memory.ROMFilename, drive, dir, fname, ext);
_makepath(filePath[index], drive, dir, fname, inExt);
}
}
else
{
_splitpath(Memory.ROMFilename, drive, dir, fname, ext);
_makepath(filePath[index], drive, dir, fname, inExt);
}
return (filePath[index]);
}
const char * S9xGetSPCFilename (void)
{
char spcExt[16];
sprintf(spcExt, ".%03d.spc", (int) spcFileCount);
spcFileCount++;
if (spcFileCount == 1000)
spcFileCount = 0;
return (S9xGetFilename(spcExt, SPC_DIR));
}
const char * S9xGetPNGFilename (void)
{
char pngExt[16];
sprintf(pngExt, ".%03d.png", (int) pngFileCount);
pngFileCount++;
if (pngFileCount == 1000)
pngFileCount = 0;
return (S9xGetFilename(pngExt, SCREENSHOT_DIR));
}
const char * S9xGetFreezeFilename (int which)
{
char frzExt[16];
sprintf(frzExt, ".%03d.frz", which);
return (S9xGetFilename(frzExt, SNAPSHOT_DIR));
}
const char * S9xGetFilenameInc (const char *inExt, enum s9x_getdirtype dirtype)
{
uint32 type;
const char *p;
if (strlen(inExt) < 4)
return (NULL);
p = inExt + strlen(inExt) - 4;
type = ((uint32) p[0] << 24) + ((uint32) p[1] << 16) + ((uint32) p[2] << 8) + (uint32) p[3];
switch (type)
{
case '.spc':
return (S9xGetSPCFilename());
case '.png':
return (S9xGetPNGFilename());
}
return (NULL);
}
const char * S9xChooseFilename (bool8 read_only)
{
return (NULL);
}
const char * S9xChooseMovieFilename (bool8 read_only)
{
return (NULL);
}
bool8 S9xOpenSnapshotFile (const char *fname, bool8 read_only, STREAM *file)
{
if (read_only)
{
if (0 != (*file = OPEN_STREAM(fname, "rb")))
return (true);
}
else
{
if (0 != (*file = OPEN_STREAM(fname, "wb")))
return (true);
}
return (false);
}
void S9xCloseSnapshotFile (STREAM file)
{
CLOSE_STREAM(file);
}
const char * S9xBasename (const char *in)
{
static char s[PATH_MAX + 1];
strncpy(s, in, PATH_MAX + 1);
s[PATH_MAX] = 0;
size_t l = strlen(s);
for (unsigned int i = 0; i < l; i++)
{
if (s[i] < 32 || s[i] >= 127)
s[i] = '_';
}
return (basename(s));
}
const char * S9xGetDirectory (enum s9x_getdirtype dirtype)
{
static int index = 0;
static char path[4][PATH_MAX + 1];
char inExt[16];
char drive[_MAX_DRIVE + 1], dir[_MAX_DIR + 1], fname[_MAX_FNAME + 1], ext[_MAX_EXT + 1];
index++;
if (index > 3)
index = 0;
switch (dirtype)
{
case SNAPSHOT_DIR: strcpy(inExt, ".frz"); break;
case SRAM_DIR: strcpy(inExt, ".srm"); break;
case SCREENSHOT_DIR: strcpy(inExt, ".png"); break;
case SPC_DIR: strcpy(inExt, ".spc"); break;
case CHEAT_DIR: strcpy(inExt, ".cht"); break;
case BIOS_DIR: strcpy(inExt, ".bio"); break;
case LOG_DIR: strcpy(inExt, ".log"); break;
default: strcpy(inExt, ".xxx"); break;
}
_splitpath(S9xGetFilename(inExt, dirtype), drive, dir, fname, ext);
_makepath(path[index], drive, dir, "", "");
size_t l = strlen(path[index]);
if (l > 1)
path[index][l - 1] = 0;
return (path[index]);
}
void _splitpath (const char *path, char *drive, char *dir, char *fname, char *ext)
{
drive[0] = 0;
fname[0] = 0;
ext[0] = 0;
dir[0] = 0;
size_t x;
x = strlen(path) - 1;
if (x < 0)
return;
while (x && (path[x] != MAC_PATH_SEP_CHAR))
x--;
if (x)
{
strcpy(dir, path);
dir[x + 1] = 0;
strcpy(fname, path + x + 1);
}
else
strcpy(fname, path);
x = strlen(fname);
while (x && (fname[x] != '.'))
x--;
if (x)
{
strcpy(ext, fname + x);
fname[x] = 0;
}
}
void _makepath (char *path, const char *drive, const char *dir, const char *fname, const char *ext)
{
static const char emp[] = "", dot[] = ".";
const char *d, *f, *e, *p;
d = dir ? dir : emp;
f = fname ? fname : emp;
e = ext ? ext : emp;
p = (e[0] && e[0] != '.') ? dot : emp;
snprintf(path, PATH_MAX + 1, "%s%s%s%s", d, f, p, e);
}

View File

@ -15,15 +15,16 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/
#undef READ_WORD(s) #undef READ_WORD
#undef READ_3WORD(s) #undef READ_3WORD
#undef READ_DWORD(s) #undef READ_DWORD
#undef WRITE_WORD(s, d) #undef WRITE_WORD
#undef WRITE_3WORD(s, d) #undef WRITE_3WORD
#undef WRITE_DWORD(s, d) #undef WRITE_DWORD
#define ZLIB #define ZLIB
#define UNZIP_SUPPORT #define UNZIP_SUPPORT

View File

@ -15,6 +15,7 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/

View File

@ -15,6 +15,7 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/
@ -57,12 +58,7 @@ void DrawSubCGImage (CGContextRef ctx, CGImageRef image, CGRect src, CGRect dst)
static void SetIconImage (CGImageRef image, CGRect rct, int n) static void SetIconImage (CGImageRef image, CGRect rct, int n)
{ {
if (systemVersion >= 0x1040) macIconImage[n] = CGImageCreateWithImageInRect(image, rct);
macIconImage[n] = CGImageCreateWithImageInRect(image, rct);
#ifdef MAC_PANTHER_SUPPORT
else
macIconRef[n] = CreateIconRefFromImage(image, rct);
#endif
} }
void CreateIconImages (void) void CreateIconImages (void)
@ -160,18 +156,8 @@ void ReleaseIconImages (void)
{ {
for (int i = 0; i < 118; i++) for (int i = 0; i < 118; i++)
{ {
if (systemVersion >= 0x1040) if (macIconImage[i])
{ CGImageRelease(macIconImage[i]);
if (macIconImage[i])
CGImageRelease(macIconImage[i]);
}
#ifdef MAC_PANTHER_SUPPORT
else
{
if (macIconRef[i])
ReleaseIconRef(macIconRef[i]);
}
#endif
} }
#ifdef MAC_PANTHER_SUPPORT #ifdef MAC_PANTHER_SUPPORT

File diff suppressed because it is too large Load Diff

View File

@ -15,154 +15,124 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/
#ifndef _mac_joypad_h_ #ifndef _mac_joypad_h_
#define _mac_joypad_h_ #define _mac_joypad_h_
enum #include <string>
{ #include <unordered_map>
kISp1PUp = 0, #include <unordered_set>
kISp1PDn,
kISp1PLf,
kISp1PRt,
kISp2PUp, #include "mac-controls.h"
kISp2PDn,
kISp2PLf,
kISp2PRt,
kISp3PUp, struct JoypadDevice {
kISp3PDn, uint16 vendorID;
kISp3PLf, uint16 productID;
kISp3PRt, uint32 index;
kISp4PUp, bool operator==(const struct JoypadDevice &o) const
kISp4PDn, {
kISp4PLf, return vendorID == o.vendorID && productID == o.productID && index == o.index;
kISp4PRt, }
kISp5PUp, bool operator<(const struct JoypadDevice &o) const
kISp5PDn, {
kISp5PLf, return vendorID < o.vendorID || productID < o.productID || index < o.index;
kISp5PRt, }
kISp6PUp,
kISp6PDn,
kISp6PLf,
kISp6PRt,
kISp7PUp,
kISp7PDn,
kISp7PLf,
kISp7PRt,
kISp8PUp,
kISp8PDn,
kISp8PLf,
kISp8PRt,
kISp1PB,
kISp1PA,
kISp1PX,
kISp1PY,
kISp1PL,
kISp1PR,
kISp1PSelect,
kISp1PStart,
kISp2PB,
kISp2PA,
kISp2PX,
kISp2PY,
kISp2PL,
kISp2PR,
kISp2PSelect,
kISp2PStart,
kISp3PB,
kISp3PA,
kISp3PX,
kISp3PY,
kISp3PL,
kISp3PR,
kISp3PSelect,
kISp3PStart,
kISp4PB,
kISp4PA,
kISp4PX,
kISp4PY,
kISp4PL,
kISp4PR,
kISp4PSelect,
kISp4PStart,
kISp5PB,
kISp5PA,
kISp5PX,
kISp5PY,
kISp5PL,
kISp5PR,
kISp5PSelect,
kISp5PStart,
kISp6PB,
kISp6PA,
kISp6PX,
kISp6PY,
kISp6PL,
kISp6PR,
kISp6PSelect,
kISp6PStart,
kISp7PB,
kISp7PA,
kISp7PX,
kISp7PY,
kISp7PL,
kISp7PR,
kISp7PSelect,
kISp7PStart,
kISp8PB,
kISp8PA,
kISp8PX,
kISp8PY,
kISp8PL,
kISp8PR,
kISp8PSelect,
kISp8PStart,
kISpFastForward,
kISpFreeze,
kISpDefrost,
kISpScreenshot,
kISpEsc,
kISpSPC,
kISpMouseL,
kISpMouseR,
kISpScopeT,
kISpScopeP,
kISpScopeC,
kISpOffScreen,
kISpFunction,
kISpAlt,
kISpFFUp,
kISpFFDown,
kISpTC,
kNeedCount
}; };
struct JoypadCookie {
struct JoypadDevice device;
uint32 cookie;
JoypadCookie() {}
struct JoypadCookie &operator=(const struct JoypadCookie &o)
{
device = o.device;
cookie = o.cookie;
return *this;
}
bool operator==(const struct JoypadCookie &o) const
{
return device == o.device && cookie == o.cookie;
}
bool operator<(const struct JoypadCookie &o) const
{
return device < o.device || cookie < o.cookie;
}
};
struct JoypadCookieInfo {
uint32 usage;
uint32 index;
int32 midpoint;
int32 min;
int32 max;
};
struct JoypadInput {
struct JoypadCookie cookie;
int32 value;
bool operator==(const struct JoypadInput &o) const
{
return cookie == o.cookie && value == o.value;
}
bool operator<(const struct JoypadInput &o) const
{
return cookie < o.cookie || value < o.value;
}
};
namespace std {
template <>
struct hash<struct JoypadDevice>
{
std::size_t operator()(const JoypadDevice& k) const
{
return k.vendorID ^ k.productID ^ k.index;
}
};
template <>
struct hash<struct JoypadCookie>
{
std::size_t operator()(const JoypadCookie& k) const
{
return std::hash<struct JoypadDevice>()(k.device) ^ k.cookie;
}
};
template <>
struct hash<struct JoypadInput>
{
std::size_t operator()(const JoypadInput& k) const
{
return std::hash<struct JoypadCookie>()(k.cookie) ^ k.value;
}
};
}
void SetUpHID (void); void SetUpHID (void);
void ReleaseHID (void); void ReleaseHID (void);
void ConfigureHID (void);
void ClearPadSetting (void); std::unordered_set<struct JoypadDevice> ListJoypads (void);
void SaveControllerSettings (void); std::string NameForDevice(struct JoypadDevice device);
void LoadControllerSettings (void);
long ISpKeyIsPressed (int); void SetPlayerForJoypad(int8 playerNum, uint32 vendorID, uint32 productID, uint32 index, int8 *oldPlayerNum);
void JoypadScanDirection (int, uint32 *); bool SetButtonCodeForJoypadControl(uint32 vendorID, uint32 productID, uint32 index, uint32 cookie, int32 value, S9xButtonCode buttonCode, bool overwrite, S9xButtonCode *oldButtonCode);
void ClearButtonCodeForJoypad(uint32 vendorID, uint32 productID, uint32 index, S9xButtonCode buttonCode);
void ClearJoypad(uint32 vendorID, uint32 productID, uint32 index);
std::unordered_map<struct JoypadInput, S9xButtonCode> GetJuypadButtons(uint32 vendorID, uint32 productID, uint32 index);
std::string LabelForInput(uint32 vendorID, uint32 productID, uint32 cookie, int32 value);
#endif #endif

1043
macosx/mac-joypad.mm Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -15,63 +15,28 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/
#ifndef _mac_keyboard_h_ #ifndef _mac_keyboard_h_
#define _mac_keyboard_h_ #define _mac_keyboard_h_
#define kKeys 39 #include "mac-controls.h"
extern uint8 keyCode[kKeys]; #define MAC_NUM_KEYCODES 255
enum struct S9xButton {
{ int16 buttonCode;
k1PUp, int8 player;
k1PDown,
k1PLeft,
k1PRight,
k1PY,
k1PB,
k1PX,
k1PA,
k1PL,
k1PR,
k1PStart,
k1PSelect,
k2PUp,
k2PDown,
k2PLeft,
k2PRight,
k2PY,
k2PB,
k2PX,
k2PA,
k2PL,
k2PR,
k2PStart,
k2PSelect,
kKeyFastForward,
kKeyFreeze,
kKeyDefrost,
kKeyScreenshot,
kKeySPC,
kKeyScopeTurbo,
kKeyScopePause,
kKeyScopeCursor,
kKeyOffScreen,
kKeyFunction,
kKeyAlt,
kKeyFFDown,
kKeyFFUp,
kKeyEsc,
kKeyTC
}; };
extern struct S9xButton keyCodes[MAC_NUM_KEYCODES];
void InitKeyboard (void); void InitKeyboard (void);
void DeinitKeyboard (void); void DeinitKeyboard (void);
void ConfigureKeyboard (void);
bool SetKeyCode(int16 keyCode, S9xButtonCode button, int8 player, int16 *oldKeyCode, S9xButtonCode *oldButton, int8 *oldPlayer);
void ClearKeyCode(S9xButtonCode buttonCode, int8 player);
#endif #endif

100
macosx/mac-keyboard.mm Executable file
View File

@ -0,0 +1,100 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#include <Cocoa/Cocoa.h>
#include "port.h"
#include "mac-prefix.h"
#include "mac-dialog.h"
#include "mac-gworld.h"
#include "mac-os.h"
#include "mac-keyboard.h"
struct S9xButton keyCodes[MAC_NUM_KEYCODES];
void InitKeyboard (void)
{
for (int i = 0; i < MAC_NUM_KEYCODES; ++i)
{
keyCodes[i] = { -1, -1 };
}
}
void DeinitKeyboard (void)
{
for (int i = 0; i < MAC_NUM_KEYCODES; ++i)
{
keyCodes[i] = { -1, -1 };
}
}
bool SetKeyCode(int16 keyCode, S9xButtonCode buttonCode, int8 player, int16 *oldKeyCode, S9xButtonCode *oldButtonCode, int8 *oldPlayer)
{
if (player < 0 || player >= MAC_MAX_PLAYERS || buttonCode < 0 || buttonCode >= kNumButtons)
{
return false;
}
for ( int i = 0; i < MAC_NUM_KEYCODES; ++i)
{
struct S9xButton button = keyCodes[i];
if (button.player == player && button.buttonCode == buttonCode && i != keyCode)
{
keyCodes[i] = { -1, -1 };
if (oldKeyCode !=NULL)
{
*oldKeyCode = i;
}
}
}
if (oldButtonCode != NULL)
{
*oldButtonCode = (S9xButtonCode)keyCodes[keyCode].buttonCode;
}
if (oldPlayer != NULL )
{
*oldPlayer = (S9xButtonCode)keyCodes[keyCode].player;
}
keyCodes[keyCode] = { static_cast<int16>(buttonCode), player };
return true;
}
void ClearKeyCode(S9xButtonCode buttonCode, int8 player)
{
if (player < 0 || player >= MAC_MAX_PLAYERS || buttonCode < 0 || buttonCode >= kNumButtons)
{
return;
}
for ( int i = 0; i < MAC_NUM_KEYCODES; ++i)
{
struct S9xButton button = keyCodes[i];
if (button.player == player && button.buttonCode == buttonCode)
{
keyCodes[i] = { -1, -1 };
}
}
}

View File

@ -1,534 +0,0 @@
/*****************************************************************************\
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 "port.h"
#include "mac-prefix.h"
#include "mac-cart.h"
#include "mac-dialog.h"
#include "mac-os.h"
#include "mac-multicart.h"
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
#define truncEnd 0
#endif
static pascal OSStatus MultiCartEventHandler (EventHandlerCallRef, EventRef, void *);
static pascal OSStatus MultiCartPaneEventHandler (EventHandlerCallRef, EventRef, void *);
static int multiCartDragHilite;
static Boolean multiCartDialogResult;
void InitMultiCart (void)
{
CFStringRef keyRef, pathRef;
char key[32];
multiCartPath[0] = multiCartPath[1] = NULL;
for (int i = 0; i < 2; i++)
{
sprintf(key, "MultiCartPath_%02d", i);
keyRef = CFStringCreateWithCString(kCFAllocatorDefault, key, CFStringGetSystemEncoding());
if (keyRef)
{
pathRef = (CFStringRef) CFPreferencesCopyAppValue(keyRef, kCFPreferencesCurrentApplication);
if (pathRef)
multiCartPath[i] = pathRef;
CFRelease(keyRef);
}
}
}
void DeinitMultiCart (void)
{
CFStringRef keyRef;
char key[32];
for (int i = 0; i < 2; i++)
{
sprintf(key, "MultiCartPath_%02d", i);
keyRef = CFStringCreateWithCString(kCFAllocatorDefault, key, CFStringGetSystemEncoding());
if (keyRef)
{
if (multiCartPath[i])
{
CFPreferencesSetAppValue(keyRef, multiCartPath[i], kCFPreferencesCurrentApplication);
CFRelease(multiCartPath[i]);
}
else
CFPreferencesSetAppValue(keyRef, NULL, kCFPreferencesCurrentApplication);
CFRelease(keyRef);
}
}
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
}
Boolean MultiCartDialog (void)
{
OSStatus err;
IBNibRef nibRef;
multiCartDragHilite = -1;
multiCartDialogResult = false;
err = CreateNibReference(kMacS9XCFString, &nibRef);
if (err == noErr)
{
WindowRef window;
err = CreateWindowFromNib(nibRef, CFSTR("MultiCart"), &window);
if (err == noErr)
{
static int index[2] = { 0, 1 };
EventHandlerRef wRef, cRef[2];
EventHandlerUPP wUPP, cUPP[2];
EventTypeSpec wEvent[] = { { kEventClassCommand, kEventCommandProcess },
{ kEventClassCommand, kEventCommandUpdateStatus } },
cEvent[] = { { kEventClassControl, kEventControlDraw },
{ kEventClassControl, kEventControlDragEnter },
{ kEventClassControl, kEventControlDragWithin },
{ kEventClassControl, kEventControlDragLeave },
{ kEventClassControl, kEventControlDragReceive } };
HIViewRef ctl, root, pane[2];
HIViewID cid;
root = HIViewGetRoot(window);
wUPP = NewEventHandlerUPP(MultiCartEventHandler);
err = InstallWindowEventHandler(window, wUPP, GetEventTypeCount(wEvent), wEvent, (void *) window, &wRef);
err = SetAutomaticControlDragTrackingEnabledForWindow(window, true);
for (int i = 0; i < 2; i++)
{
cid.id = i;
cid.signature = 'MPan';
HIViewFindByID(root, cid, &pane[i]);
cUPP[i] = NewEventHandlerUPP(MultiCartPaneEventHandler);
err = InstallControlEventHandler(pane[i], cUPP[i], GetEventTypeCount(cEvent), cEvent, (void *) &index[i], &cRef[i]);
err = SetControlDragTrackingEnabled(pane[i], true);
cid.signature = 'MNAM';
HIViewFindByID(root, cid, &ctl);
SetStaticTextTrunc(ctl, truncEnd, false);
if (multiCartPath[i])
{
CFStringRef str;
CFURLRef url;
url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, multiCartPath[i], kCFURLPOSIXPathStyle, false);
str = CFURLCopyLastPathComponent(url);
SetStaticTextCFString(ctl, str, false);
CFRelease(str);
CFRelease(url);
}
else
SetStaticTextCFString(ctl, CFSTR(""), false);
}
MoveWindowPosition(window, kWindowMultiCart, false);
ShowWindow(window);
err = RunAppModalLoopForWindow(window);
HideWindow(window);
SaveWindowPosition(window, kWindowMultiCart);
for (int i = 0; i < 2; i++)
{
err = RemoveEventHandler(cRef[i]);
DisposeEventHandlerUPP(cUPP[i]);
}
err = RemoveEventHandler(wRef);
DisposeEventHandlerUPP(wUPP);
CFRelease(window);
}
DisposeNibReference(nibRef);
}
return (multiCartDialogResult);
}
static pascal OSStatus MultiCartEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
{
OSStatus err, result = eventNotHandledErr;
WindowRef window = (WindowRef) inUserData;
static int index = -1;
switch (GetEventClass(inEvent))
{
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(false);
result = noErr;
}
break;
}
case kEventCommandProcess:
{
err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
if (err == noErr)
{
HIViewRef ctl, root;
HIViewID cid;
FSRef ref;
bool8 r;
root = HIViewGetRoot(window);
switch (tHICommand.commandID)
{
case 'Cho0':
case 'Cho1':
{
index = (tHICommand.commandID & 0xFF) - '0';
r = NavBeginOpenROMImageSheet(window, NULL);
result = noErr;
break;
}
case 'NvDn':
{
r = NavEndOpenROMImageSheet(&ref);
if (r)
{
CFStringRef str;
CFURLRef url;
url = CFURLCreateFromFSRef(kCFAllocatorDefault, &ref);
str = CFURLCopyLastPathComponent(url);
cid.signature = 'MNAM';
cid.id = index;
HIViewFindByID(root, cid, &ctl);
SetStaticTextCFString(ctl, str, true);
CFRelease(str);
str = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
if (multiCartPath[index])
CFRelease(multiCartPath[index]);
multiCartPath[index] = str;
CFRelease(url);
}
index = -1;
result = noErr;
break;
}
case 'Cle0':
case 'Cle1':
{
index = (tHICommand.commandID & 0xFF) - '0';
cid.signature = 'MNAM';
cid.id = index;
HIViewFindByID(root, cid, &ctl);
SetStaticTextCFString(ctl, CFSTR(""), true);
if (multiCartPath[index])
{
CFRelease(multiCartPath[index]);
multiCartPath[index] = NULL;
}
index = -1;
result = noErr;
break;
}
case 'SWAP':
{
CFStringRef str;
CFURLRef url;
str = multiCartPath[0];
multiCartPath[0] = multiCartPath[1];
multiCartPath[1] = str;
cid.signature = 'MNAM';
for (int i = 0; i < 2; i++)
{
cid.id = i;
HIViewFindByID(root, cid, &ctl);
if (multiCartPath[i])
{
url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, multiCartPath[i], kCFURLPOSIXPathStyle, false);
str = CFURLCopyLastPathComponent(url);
SetStaticTextCFString(ctl, str, true);
CFRelease(str);
CFRelease(url);
}
else
SetStaticTextCFString(ctl, CFSTR(""), true);
}
result = noErr;
break;
}
case 'ok ':
{
QuitAppModalLoopForWindow(window);
multiCartDialogResult = true;
result = noErr;
break;
}
case 'not!':
{
QuitAppModalLoopForWindow(window);
multiCartDialogResult = false;
result = noErr;
break;
}
}
}
}
}
}
}
return (result);
}
static pascal OSStatus MultiCartPaneEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
{
OSStatus err, result = eventNotHandledErr;
HIViewRef view;
DragRef drag;
PasteboardRef pasteboard;
PasteboardItemID itemID;
CFArrayRef array;
CFStringRef flavorType;
CFIndex numFlavors;
ItemCount numItems;
int index = *((int *) inUserData);
switch (GetEventClass(inEvent))
{
case kEventClassControl:
{
switch (GetEventKind(inEvent))
{
case kEventControlDraw:
{
err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view);
if (err == noErr)
{
CGContextRef ctx;
err = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(CGContextRef), NULL, &ctx);
if (err == noErr)
{
HIThemeFrameDrawInfo info;
HIRect bounds, frame;
HIViewGetBounds(view, &bounds);
CGContextSetRGBFillColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f);
CGContextFillRect(ctx, bounds);
info.version = 0;
info.kind = kHIThemeFrameTextFieldSquare;
info.state = kThemeStateInactive;
info.isFocused = false;
err = HIThemeDrawFrame(&bounds, &info, ctx, kHIThemeOrientationNormal);
if (multiCartDragHilite == index && systemVersion >= 0x1040)
{
err = HIThemeSetStroke(kThemeBrushDragHilite, NULL, ctx, kHIThemeOrientationNormal);
frame = CGRectInset(bounds, 1, 1);
CGContextBeginPath(ctx);
CGContextAddRect(ctx, frame);
CGContextStrokePath(ctx);
}
}
}
result = noErr;
break;
}
case kEventControlDragEnter:
{
err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view);
if (err == noErr)
{
err = GetEventParameter(inEvent, kEventParamDragRef, typeDragRef, NULL, sizeof(DragRef), NULL, &drag);
if (err == noErr)
{
err = GetDragPasteboard(drag, &pasteboard);
if (err == noErr)
{
err = PasteboardGetItemCount(pasteboard, &numItems);
if (err == noErr && numItems == 1)
{
err = PasteboardGetItemIdentifier(pasteboard, 1, &itemID);
if (err == noErr)
{
err = PasteboardCopyItemFlavors(pasteboard, itemID, &array);
if (err == noErr)
{
numFlavors = CFArrayGetCount(array);
for (CFIndex i = 0; i < numFlavors; i++)
{
flavorType = (CFStringRef) CFArrayGetValueAtIndex(array, i);
if (UTTypeConformsTo(flavorType, CFSTR("public.file-url")))
{
Boolean accept = true;
err = SetEventParameter(inEvent, kEventParamControlWouldAcceptDrop, typeBoolean, sizeof(Boolean), &accept);
if (err == noErr)
{
multiCartDragHilite = index;
HIViewSetNeedsDisplay(view, true);
result = noErr;
}
}
}
CFRelease(array);
}
}
}
}
}
}
break;
}
case kEventControlDragWithin:
{
result = noErr;
break;
}
case kEventControlDragLeave:
{
err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view);
if (err == noErr)
{
multiCartDragHilite = -1;
HIViewSetNeedsDisplay(view, true);
}
result = noErr;
break;
}
case kEventControlDragReceive:
{
err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view);
if (err == noErr)
{
err = GetEventParameter(inEvent, kEventParamDragRef, typeDragRef, NULL, sizeof(DragRef), NULL, &drag);
if (err == noErr)
{
multiCartDragHilite = -1;
HIViewSetNeedsDisplay(view, true);
err = GetDragPasteboard(drag, &pasteboard);
if (err == noErr)
{
err = PasteboardGetItemIdentifier(pasteboard, 1, &itemID);
if (err == noErr)
{
err = PasteboardCopyItemFlavors(pasteboard, itemID, &array);
if (err == noErr)
{
numFlavors = CFArrayGetCount(array);
for (CFIndex i = 0; i < numFlavors; i++)
{
flavorType = (CFStringRef) CFArrayGetValueAtIndex(array, i);
if (UTTypeConformsTo(flavorType, CFSTR("public.file-url")))
{
CFDataRef flavorData;
err = PasteboardCopyItemFlavorData(pasteboard, itemID, flavorType, &flavorData);
if (err == noErr)
{
CFIndex dataSize;
UInt8 *data;
dataSize = CFDataGetLength(flavorData);
data = (UInt8 *) malloc(dataSize);
if (data)
{
CFDataGetBytes(flavorData, CFRangeMake(0, dataSize), data);
HIViewRef ctl;
HIViewID cid;
CFStringRef str;
CFURLRef url;
GetControlID(view, &cid);
cid.signature = 'MNAM';
HIViewFindByID(view, cid, &ctl);
url = CFURLCreateWithBytes(kCFAllocatorDefault, data, dataSize, kCFStringEncodingUTF8, NULL);
str = CFURLCopyLastPathComponent(url);
SetStaticTextCFString(ctl, str, true);
CFRelease(str);
str = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
if (multiCartPath[cid.id])
CFRelease(multiCartPath[cid.id]);
multiCartPath[cid.id] = str;
CFRelease(url);
result = noErr;
free(data);
}
CFRelease(flavorData);
}
}
}
CFRelease(array);
}
}
}
}
}
}
}
}
}
return (result);
}

View File

@ -15,6 +15,7 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/

540
macosx/mac-multicart.mm Normal file
View File

@ -0,0 +1,540 @@
/*****************************************************************************\
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
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#include "port.h"
#include "mac-prefix.h"
#include "mac-cart.h"
#include "mac-dialog.h"
#include "mac-os.h"
#include "mac-multicart.h"
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
#define truncEnd 0
#endif
static OSStatus MultiCartEventHandler (EventHandlerCallRef, EventRef, void *);
static OSStatus MultiCartPaneEventHandler (EventHandlerCallRef, EventRef, void *);
static int multiCartDragHilite;
static Boolean multiCartDialogResult;
void InitMultiCart (void)
{
CFStringRef keyRef, pathRef;
char key[32];
multiCartPath[0] = multiCartPath[1] = NULL;
for (int i = 0; i < 2; i++)
{
sprintf(key, "MultiCartPath_%02d", i);
keyRef = CFStringCreateWithCString(kCFAllocatorDefault, key, CFStringGetSystemEncoding());
if (keyRef)
{
pathRef = (CFStringRef) CFPreferencesCopyAppValue(keyRef, kCFPreferencesCurrentApplication);
if (pathRef)
multiCartPath[i] = pathRef;
CFRelease(keyRef);
}
}
}
void DeinitMultiCart (void)
{
CFStringRef keyRef;
char key[32];
for (int i = 0; i < 2; i++)
{
sprintf(key, "MultiCartPath_%02d", i);
keyRef = CFStringCreateWithCString(kCFAllocatorDefault, key, CFStringGetSystemEncoding());
if (keyRef)
{
if (multiCartPath[i])
{
CFPreferencesSetAppValue(keyRef, multiCartPath[i], kCFPreferencesCurrentApplication);
CFRelease(multiCartPath[i]);
}
else
CFPreferencesSetAppValue(keyRef, NULL, kCFPreferencesCurrentApplication);
CFRelease(keyRef);
}
}
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
}
Boolean MultiCartDialog (void)
{
// OSStatus err;
// IBNibRef nibRef;
//
// multiCartDragHilite = -1;
// multiCartDialogResult = false;
//
// err = CreateNibReference(kMacS9XCFString, &nibRef);
// if (err == noErr)
// {
// WindowRef window;
//
// err = CreateWindowFromNib(nibRef, CFSTR("MultiCart"), &window);
// if (err == noErr)
// {
// static int index[2] = { 0, 1 };
//
// EventHandlerRef wRef, cRef[2];
// EventHandlerUPP wUPP, cUPP[2];
// EventTypeSpec wEvent[] = { { kEventClassCommand, kEventCommandProcess },
// { kEventClassCommand, kEventCommandUpdateStatus } },
// cEvent[] = { { kEventClassControl, kEventControlDraw },
// { kEventClassControl, kEventControlDragEnter },
// { kEventClassControl, kEventControlDragWithin },
// { kEventClassControl, kEventControlDragLeave },
// { kEventClassControl, kEventControlDragReceive } };
// HIViewRef ctl, root, pane[2];
// HIViewID cid;
//
// root = HIViewGetRoot(window);
//
// wUPP = NewEventHandlerUPP(MultiCartEventHandler);
// err = InstallWindowEventHandler(window, wUPP, GetEventTypeCount(wEvent), wEvent, (void *) window, &wRef);
// err = SetAutomaticControlDragTrackingEnabledForWindow(window, true);
//
// for (int i = 0; i < 2; i++)
// {
// cid.id = i;
//
// cid.signature = 'MPan';
// HIViewFindByID(root, cid, &pane[i]);
// cUPP[i] = NewEventHandlerUPP(MultiCartPaneEventHandler);
// err = InstallControlEventHandler(pane[i], cUPP[i], GetEventTypeCount(cEvent), cEvent, (void *) &index[i], &cRef[i]);
// err = SetControlDragTrackingEnabled(pane[i], true);
//
// cid.signature = 'MNAM';
// HIViewFindByID(root, cid, &ctl);
// SetStaticTextTrunc(ctl, truncEnd, false);
// if (multiCartPath[i])
// {
// CFStringRef str;
// CFURLRef url;
//
// url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, multiCartPath[i], kCFURLPOSIXPathStyle, false);
// str = CFURLCopyLastPathComponent(url);
// SetStaticTextCFString(ctl, str, false);
// CFRelease(str);
// CFRelease(url);
// }
// else
// SetStaticTextCFString(ctl, CFSTR(""), false);
// }
//
// MoveWindowPosition(window, kWindowMultiCart, false);
// ShowWindow(window);
// err = RunAppModalLoopForWindow(window);
// HideWindow(window);
// SaveWindowPosition(window, kWindowMultiCart);
//
// for (int i = 0; i < 2; i++)
// {
// err = RemoveEventHandler(cRef[i]);
// DisposeEventHandlerUPP(cUPP[i]);
// }
//
// err = RemoveEventHandler(wRef);
// DisposeEventHandlerUPP(wUPP);
//
// CFRelease(window);
// }
//
// DisposeNibReference(nibRef);
// }
//
// return (multiCartDialogResult);
return 0;
}
static OSStatus MultiCartEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
{
// OSStatus err, result = eventNotHandledErr;
// WindowRef window = (WindowRef) inUserData;
// static int index = -1;
//
// switch (GetEventClass(inEvent))
// {
// 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(false);
// result = noErr;
// }
//
// break;
// }
//
// case kEventCommandProcess:
// {
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
// if (err == noErr)
// {
// HIViewRef ctl, root;
// HIViewID cid;
// FSRef ref;
// bool8 r;
//
// root = HIViewGetRoot(window);
//
// switch (tHICommand.commandID)
// {
// case 'Cho0':
// case 'Cho1':
// {
// index = (tHICommand.commandID & 0xFF) - '0';
// // r = NavBeginOpenROMImageSheet(window, NULL);
// result = noErr;
// break;
// }
//
// case 'NvDn':
// {
// r = NavEndOpenROMImageSheet(&ref);
// if (r)
// {
// CFStringRef str;
// CFURLRef url;
//
// url = CFURLCreateFromFSRef(kCFAllocatorDefault, &ref);
// str = CFURLCopyLastPathComponent(url);
// cid.signature = 'MNAM';
// cid.id = index;
// HIViewFindByID(root, cid, &ctl);
// SetStaticTextCFString(ctl, str, true);
// CFRelease(str);
// str = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
// if (multiCartPath[index])
// CFRelease(multiCartPath[index]);
// multiCartPath[index] = str;
// CFRelease(url);
// }
//
// index = -1;
// result = noErr;
// break;
// }
//
// case 'Cle0':
// case 'Cle1':
// {
// index = (tHICommand.commandID & 0xFF) - '0';
// cid.signature = 'MNAM';
// cid.id = index;
// HIViewFindByID(root, cid, &ctl);
// SetStaticTextCFString(ctl, CFSTR(""), true);
// if (multiCartPath[index])
// {
// CFRelease(multiCartPath[index]);
// multiCartPath[index] = NULL;
// }
//
// index = -1;
// result = noErr;
// break;
// }
//
// case 'SWAP':
// {
// CFStringRef str;
// CFURLRef url;
//
// str = multiCartPath[0];
// multiCartPath[0] = multiCartPath[1];
// multiCartPath[1] = str;
//
// cid.signature = 'MNAM';
//
// for (int i = 0; i < 2; i++)
// {
// cid.id = i;
// HIViewFindByID(root, cid, &ctl);
//
// if (multiCartPath[i])
// {
// url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, multiCartPath[i], kCFURLPOSIXPathStyle, false);
// str = CFURLCopyLastPathComponent(url);
// SetStaticTextCFString(ctl, str, true);
// CFRelease(str);
// CFRelease(url);
// }
// else
// SetStaticTextCFString(ctl, CFSTR(""), true);
// }
//
// result = noErr;
// break;
// }
//
// case 'ok ':
// {
// QuitAppModalLoopForWindow(window);
// multiCartDialogResult = true;
// result = noErr;
// break;
// }
//
// case 'not!':
// {
// QuitAppModalLoopForWindow(window);
// multiCartDialogResult = false;
// result = noErr;
// break;
// }
// }
// }
// }
// }
// }
// }
//
// return (result);
return 0;
}
static OSStatus MultiCartPaneEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
{
// OSStatus err, result = eventNotHandledErr;
// HIViewRef view;
// DragRef drag;
// PasteboardRef pasteboard;
// PasteboardItemID itemID;
// CFArrayRef array;
// CFStringRef flavorType;
// CFIndex numFlavors;
// ItemCount numItems;
// int index = *((int *) inUserData);
//
// switch (GetEventClass(inEvent))
// {
// case kEventClassControl:
// {
// switch (GetEventKind(inEvent))
// {
// case kEventControlDraw:
// {
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view);
// if (err == noErr)
// {
// CGContextRef ctx;
//
// err = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(CGContextRef), NULL, &ctx);
// if (err == noErr)
// {
// HIThemeFrameDrawInfo info;
// HIRect bounds, frame;
//
// HIViewGetBounds(view, &bounds);
//
// CGContextSetRGBFillColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f);
// CGContextFillRect(ctx, bounds);
//
// info.version = 0;
// info.kind = kHIThemeFrameTextFieldSquare;
// info.state = kThemeStateInactive;
// info.isFocused = false;
// err = HIThemeDrawFrame(&bounds, &info, ctx, kHIThemeOrientationNormal);
//
// if (multiCartDragHilite == index && systemVersion >= 0x1040)
// {
// err = HIThemeSetStroke(kThemeBrushDragHilite, NULL, ctx, kHIThemeOrientationNormal);
// frame = CGRectInset(bounds, 1, 1);
// CGContextBeginPath(ctx);
// CGContextAddRect(ctx, frame);
// CGContextStrokePath(ctx);
// }
// }
// }
//
// result = noErr;
// break;
// }
//
// case kEventControlDragEnter:
// {
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view);
// if (err == noErr)
// {
// err = GetEventParameter(inEvent, kEventParamDragRef, typeDragRef, NULL, sizeof(DragRef), NULL, &drag);
// if (err == noErr)
// {
// err = GetDragPasteboard(drag, &pasteboard);
// if (err == noErr)
// {
// err = PasteboardGetItemCount(pasteboard, &numItems);
// if (err == noErr && numItems == 1)
// {
// err = PasteboardGetItemIdentifier(pasteboard, 1, &itemID);
// if (err == noErr)
// {
// err = PasteboardCopyItemFlavors(pasteboard, itemID, &array);
// if (err == noErr)
// {
// numFlavors = CFArrayGetCount(array);
// for (CFIndex i = 0; i < numFlavors; i++)
// {
// flavorType = (CFStringRef) CFArrayGetValueAtIndex(array, i);
// if (UTTypeConformsTo(flavorType, CFSTR("public.file-url")))
// {
// Boolean accept = true;
//
// err = SetEventParameter(inEvent, kEventParamControlWouldAcceptDrop, typeBoolean, sizeof(Boolean), &accept);
// if (err == noErr)
// {
// multiCartDragHilite = index;
// HIViewSetNeedsDisplay(view, true);
// result = noErr;
// }
// }
// }
//
// CFRelease(array);
// }
// }
// }
// }
// }
// }
//
// break;
// }
//
// case kEventControlDragWithin:
// {
// result = noErr;
// break;
// }
//
// case kEventControlDragLeave:
// {
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view);
// if (err == noErr)
// {
// multiCartDragHilite = -1;
// HIViewSetNeedsDisplay(view, true);
// }
//
// result = noErr;
// break;
// }
//
// case kEventControlDragReceive:
// {
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view);
// if (err == noErr)
// {
// err = GetEventParameter(inEvent, kEventParamDragRef, typeDragRef, NULL, sizeof(DragRef), NULL, &drag);
// if (err == noErr)
// {
// multiCartDragHilite = -1;
// HIViewSetNeedsDisplay(view, true);
//
// err = GetDragPasteboard(drag, &pasteboard);
// if (err == noErr)
// {
// err = PasteboardGetItemIdentifier(pasteboard, 1, &itemID);
// if (err == noErr)
// {
// err = PasteboardCopyItemFlavors(pasteboard, itemID, &array);
// if (err == noErr)
// {
// numFlavors = CFArrayGetCount(array);
// for (CFIndex i = 0; i < numFlavors; i++)
// {
// flavorType = (CFStringRef) CFArrayGetValueAtIndex(array, i);
// if (UTTypeConformsTo(flavorType, CFSTR("public.file-url")))
// {
// CFDataRef flavorData;
//
// err = PasteboardCopyItemFlavorData(pasteboard, itemID, flavorType, &flavorData);
// if (err == noErr)
// {
// CFIndex dataSize;
// UInt8 *data;
//
// dataSize = CFDataGetLength(flavorData);
// data = (UInt8 *) malloc(dataSize);
// if (data)
// {
// CFDataGetBytes(flavorData, CFRangeMake(0, dataSize), data);
//
// HIViewRef ctl;
// HIViewID cid;
// CFStringRef str;
// CFURLRef url;
//
// GetControlID(view, &cid);
// cid.signature = 'MNAM';
// HIViewFindByID(view, cid, &ctl);
//
// url = CFURLCreateWithBytes(kCFAllocatorDefault, data, dataSize, kCFStringEncodingUTF8, NULL);
// str = CFURLCopyLastPathComponent(url);
// SetStaticTextCFString(ctl, str, true);
// CFRelease(str);
// str = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
// if (multiCartPath[cid.id])
// CFRelease(multiCartPath[cid.id]);
// multiCartPath[cid.id] = str;
// CFRelease(url);
//
// result = noErr;
//
// free(data);
// }
//
// CFRelease(flavorData);
// }
// }
// }
//
// CFRelease(array);
// }
// }
// }
// }
// }
// }
// }
// }
// }
//
// return (result);
return 0;
}

View File

@ -15,6 +15,7 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/
@ -26,7 +27,7 @@
@interface MusicBoxController : NSObject @interface MusicBoxController : NSObject
{ {
IBOutlet id window; IBOutlet NSWindow *window;
IBOutlet id gametitle; IBOutlet id gametitle;
IBOutlet id disclosure; IBOutlet id disclosure;
IBOutlet id rewind; IBOutlet id rewind;

View File

@ -15,6 +15,7 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/
@ -122,7 +123,7 @@ static void * SoundTask (void *);
MacStartSound(); MacStartSound();
pthread_create(&mbxThread, NULL, SoundTask, NULL); pthread_create(&mbxThread, NULL, SoundTask, NULL);
timer = [[NSTimer scheduledTimerWithTimeInterval: (2.0 / (double) Memory.ROMFramesPerSecond) target: self selector: @selector(updateIndicator:) userInfo: nil repeats: YES] retain]; timer = [NSTimer scheduledTimerWithTimeInterval: (2.0 / (double) Memory.ROMFramesPerSecond) target: self selector: @selector(updateIndicator:) userInfo: nil repeats: YES];
return (self); return (self);
} }
@ -134,7 +135,7 @@ static void * SoundTask (void *);
BOOL r; BOOL r;
[timer invalidate]; [timer invalidate];
[timer release]; timer = nil;
showIndicator = false; showIndicator = false;
@ -159,10 +160,6 @@ static void * SoundTask (void *);
SPCPlayDefrost(); SPCPlayDefrost();
else else
MusicBoxForceDefrost(); MusicBoxForceDefrost();
[window release];
[super dealloc];
} }
- (NSWindow *) window - (NSWindow *) window
@ -268,7 +265,7 @@ static void * SoundTask (void *);
const float length[] = { 1.0f, 1.0f }; const float length[] = { 1.0f, 1.0f };
CGContextSetLineWidth(mboxctx, mbxBarWidth); CGContextSetLineWidth(mboxctx, mbxBarWidth);
CGContextSetLineDash(mboxctx, 0, length, 2); //CGContextSetLineDash(mboxctx, 0, length, 2);
CGContextSetLineJoin(mboxctx, kCGLineJoinMiter); CGContextSetLineJoin(mboxctx, kCGLineJoinMiter);
CGContextBeginPath(mboxctx); CGContextBeginPath(mboxctx);
@ -457,21 +454,14 @@ static void SPCPlayDefrost (void)
void MusicBoxDialog (void) void MusicBoxDialog (void)
{ {
MusicBoxController *controller; MusicBoxController *controller;
NSAutoreleasePool *pool;
if (!cartOpen) if (!cartOpen)
return; return;
pool = [[NSAutoreleasePool alloc] init];
controller = [[MusicBoxController alloc] init]; controller = [[MusicBoxController alloc] init];
[pool release];
if (!controller) if (!controller)
return; return;
[NSApp runModalForWindow: [controller window]]; [NSApp runModalForWindow: [controller window]];
pool = [[NSAutoreleasePool alloc] init];
[controller release];
[pool release];
} }

View File

@ -15,6 +15,7 @@
(c) Copyright 2004 Alexander and Sander (c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger (c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt (c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/ ***********************************************************************************/

Some files were not shown because too many files have changed in this diff Show More