OSDN Git Service

Imported a Mac OS X Cocoa interface from poschengband , https://github.com/NickMcConn...
authorEric Branlund <ebranlund@fastmail.com>
Sun, 25 Aug 2019 23:45:58 +0000 (16:45 -0700)
committerEric Branlund <ebranlund@fastmail.com>
Sun, 25 Aug 2019 23:45:58 +0000 (16:45 -0700)
12 files changed:
src/cocoa/.deps [new file with mode: 0644]
src/cocoa/Angband-Cocoa.xml [new file with mode: 0644]
src/cocoa/Angband_Icons.icns [new file with mode: 0644]
src/cocoa/CommandMenu.plist [new file with mode: 0644]
src/cocoa/Data.icns [new file with mode: 0644]
src/cocoa/Edit.icns [new file with mode: 0644]
src/cocoa/English.lproj/.deps [new file with mode: 0644]
src/cocoa/English.lproj/InfoPlist.strings [new file with mode: 0644]
src/cocoa/English.lproj/MainMenu.nib/designable.nib [new file with mode: 0644]
src/cocoa/English.lproj/MainMenu.nib/keyedobjects.nib [new file with mode: 0644]
src/cocoa/Save.icns [new file with mode: 0644]
src/main-cocoa.m [new file with mode: 0644]

diff --git a/src/cocoa/.deps b/src/cocoa/.deps
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/cocoa/Angband-Cocoa.xml b/src/cocoa/Angband-Cocoa.xml
new file mode 100644 (file)
index 0000000..6bae9cc
--- /dev/null
@@ -0,0 +1,87 @@
+<?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>CFBundleExecutable</key>
+       <string>$EXECUTABLE$</string>
+       <key>CFBundleIconFile</key>
+       <string>$NAME$_Icons</string>
+       <key>CFBundleIdentifier</key>
+       <string>$BUNDLE_IDENTIFIER$</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>$VERSION$</string>
+       <key>CFBundleLongVersionString</key>
+       <string>$VERSION$, Copyright $COPYRIGHT$</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>Copyright © $COPYRIGHT$</string>
+       <key>CFBundleGetInfoString</key>
+       <string>$VERSION$, © $COPYRIGHT$</string>
+       <key>CFBundleSignature</key>
+       <string>Heng</string>
+       <key>CFBundleVersion</key>
+       <string>$BUNDLE_VERSION$</string>
+       <key>CGDisableCoalescedUpdates</key>
+       <true/>
+       <key>NSMainNibFile</key>
+       <string>MainMenu</string>
+       <key>NSPrincipalClass</key>
+       <string>NSApplication</string>
+       <key>CFBundleDocumentTypes</key>
+       <array>
+               <dict>
+                       <key>CFBundleTypeExtensions</key>
+                       <array>
+                               <string>*</string>
+                       </array>
+                       <key>CFBundleTypeIconFile</key>
+                       <string>Save</string>
+                       <key>CFBundleTypeName</key>
+                       <string>$NAME$ saved game</string>
+                       <key>CFBundleTypeOSTypes</key>
+                       <array>
+                               <string>SAVE</string>
+                       </array>
+                       <key>CFBundleTypeRole</key>
+                       <string>Editor</string>
+               </dict>
+               <dict>
+                       <key>CFBundleTypeExtensions</key>
+                       <array>
+                               <string>*</string>
+                       </array>
+                       <key>CFBundleTypeIconFile</key>
+                       <string>Edit</string>
+                       <key>CFBundleTypeName</key>
+                       <string>$NAME$ game data</string>
+                       <key>CFBundleTypeOSTypes</key>
+                       <array>
+                               <string>TEXT</string>
+                       </array>
+                       <key>CFBundleTypeRole</key>
+                       <string>Editor</string>
+               </dict>
+               <dict>
+                       <key>CFBundleTypeExtensions</key>
+                       <array>
+                               <string>*</string>
+                       </array>
+                       <key>CFBundleTypeIconFile</key>
+                       <string>Data</string>
+                       <key>CFBundleTypeName</key>
+                       <string>$NAME$ game data</string>
+                       <key>CFBundleTypeOSTypes</key>
+                       <array>
+                               <string>DATA</string>
+                       </array>
+                       <key>CFBundleTypeRole</key>
+                       <string>Editor</string>
+               </dict>
+       </array>
+</dict>
+</plist>
diff --git a/src/cocoa/Angband_Icons.icns b/src/cocoa/Angband_Icons.icns
new file mode 100644 (file)
index 0000000..a8cd4dd
Binary files /dev/null and b/src/cocoa/Angband_Icons.icns differ
diff --git a/src/cocoa/CommandMenu.plist b/src/cocoa/CommandMenu.plist
new file mode 100644 (file)
index 0000000..73953ad
--- /dev/null
@@ -0,0 +1,66 @@
+<?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">
+<array>
+       <dict>
+               <key>Title</key>
+               <string>Knowledge</string>
+               <key>KeyEquivalent</key>
+               <string>k</string>
+               <key>ShiftModifier</key>
+               <false/>
+               <key>OptionModifier</key>
+               <false/>
+               <key>AngbandCommand</key>
+               <string>~</string>
+       </dict>
+       <dict>
+               <key>Title</key>
+               <string>List Monsters</string>
+               <key>KeyEquivalent</key>
+               <string>l</string>
+               <key>ShiftModifier</key>
+               <false/>
+               <key>OptionModifier</key>
+               <false/>
+               <key>AngbandCommand</key>
+               <string>[</string>
+       </dict>
+       <dict>
+               <key>Title</key>
+               <string>List Items</string>
+               <key>KeyEquivalent</key>
+               <string>l</string>
+               <key>ShiftModifier</key>
+               <true/>
+               <key>OptionModifier</key>
+               <false/>
+               <key>AngbandCommand</key>
+               <string>]</string>
+       </dict>
+       <dict>
+               <key>Title</key>
+               <string>Inscribe</string>
+               <key>KeyEquivalent</key>
+               <string>i</string>
+               <key>ShiftModifier</key>
+               <false/>
+               <key>OptionModifier</key>
+               <false/>
+               <key>AngbandCommand</key>
+               <string>{</string>
+       </dict>
+       <dict>
+               <key>Title</key>
+               <string>Uninscribe</string>
+               <key>KeyEquivalent</key>
+               <string>i</string>
+               <key>ShiftModifier</key>
+               <true/>
+               <key>OptionModifier</key>
+               <false/>
+               <key>AngbandCommand</key>
+               <string>}</string>
+       </dict>
+</array>
+</plist>
diff --git a/src/cocoa/Data.icns b/src/cocoa/Data.icns
new file mode 100644 (file)
index 0000000..67d750f
Binary files /dev/null and b/src/cocoa/Data.icns differ
diff --git a/src/cocoa/Edit.icns b/src/cocoa/Edit.icns
new file mode 100644 (file)
index 0000000..532699c
Binary files /dev/null and b/src/cocoa/Edit.icns differ
diff --git a/src/cocoa/English.lproj/.deps b/src/cocoa/English.lproj/.deps
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/cocoa/English.lproj/InfoPlist.strings b/src/cocoa/English.lproj/InfoPlist.strings
new file mode 100644 (file)
index 0000000..169bcc9
Binary files /dev/null and b/src/cocoa/English.lproj/InfoPlist.strings differ
diff --git a/src/cocoa/English.lproj/MainMenu.nib/designable.nib b/src/cocoa/English.lproj/MainMenu.nib/designable.nib
new file mode 100644 (file)
index 0000000..d5098ee
--- /dev/null
@@ -0,0 +1,1111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
+       <data>
+               <int key="IBDocument.SystemTarget">1060</int>
+               <string key="IBDocument.SystemVersion">12E55</string>
+               <string key="IBDocument.InterfaceBuilderVersion">3084</string>
+               <string key="IBDocument.AppKitVersion">1187.39</string>
+               <string key="IBDocument.HIToolboxVersion">626.00</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                       <string key="NS.object.0">3084</string>
+               </object>
+               <array key="IBDocument.IntegratedClassDependencies">
+                       <string>NSCustomObject</string>
+                       <string>NSMenu</string>
+                       <string>NSMenuItem</string>
+               </array>
+               <array key="IBDocument.PluginDependencies">
+                       <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+               </array>
+               <object class="NSMutableDictionary" key="IBDocument.Metadata">
+                       <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+                       <integer value="1" key="NS.object.0"/>
+               </object>
+               <array class="NSMutableArray" key="IBDocument.RootObjects" id="1045887612">
+                       <object class="NSCustomObject" id="1033716387">
+                               <string key="NSClassName">NSApplication</string>
+                       </object>
+                       <object class="NSCustomObject" id="515537150">
+                               <string key="NSClassName">FirstResponder</string>
+                       </object>
+                       <object class="NSCustomObject" id="848297368">
+                               <string key="NSClassName">NSApplication</string>
+                       </object>
+                       <object class="NSMenu" id="192124135">
+                               <string key="NSTitle">MainMenu</string>
+                               <array class="NSMutableArray" key="NSMenuItems">
+                                       <object class="NSMenuItem" id="688321870">
+                                               <reference key="NSMenu" ref="192124135"/>
+                                               <string key="NSTitle">Angband</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSKeyEquivModMask">1048576</int>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <object class="NSCustomResource" key="NSOnImage" id="433757408">
+                                                       <string key="NSClassName">NSImage</string>
+                                                       <string key="NSResourceName">NSMenuCheckmark</string>
+                                               </object>
+                                               <object class="NSCustomResource" key="NSMixedImage" id="336434334">
+                                                       <string key="NSClassName">NSImage</string>
+                                                       <string key="NSResourceName">NSMenuMixedState</string>
+                                               </object>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <object class="NSMenu" key="NSSubmenu" id="276135462">
+                                                       <string key="NSTitle">Angband</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="38615067">
+                                                                       <reference key="NSMenu" ref="276135462"/>
+                                                                       <string key="NSTitle">About Angband</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="428716132">
+                                                                       <reference key="NSMenu" ref="276135462"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="931707326">
+                                                                       <reference key="NSMenu" ref="276135462"/>
+                                                                       <string key="NSTitle">Preferences…</string>
+                                                                       <string key="NSKeyEquiv">,</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="698213426">
+                                                                       <reference key="NSMenu" ref="276135462"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="622427103">
+                                                                       <reference key="NSMenu" ref="276135462"/>
+                                                                       <string key="NSTitle">Services</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="595688328">
+                                                                               <object class="NSMutableString" key="NSTitle">
+                                                                                       <characters key="NS.bytes">Services</characters>
+                                                                               </object>
+                                                                               <array class="NSMutableArray" key="NSMenuItems"/>
+                                                                               <string key="NSName">_NSServicesMenu</string>
+                                                                       </object>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="478453786">
+                                                                       <reference key="NSMenu" ref="276135462"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="757690975">
+                                                                       <reference key="NSMenu" ref="276135462"/>
+                                                                       <string key="NSTitle">Hide Angband</string>
+                                                                       <string key="NSKeyEquiv">h</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="316901192">
+                                                                       <reference key="NSMenu" ref="276135462"/>
+                                                                       <string key="NSTitle">Hide Others</string>
+                                                                       <string key="NSKeyEquiv">h</string>
+                                                                       <int key="NSKeyEquivModMask">1572864</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="538675488">
+                                                                       <reference key="NSMenu" ref="276135462"/>
+                                                                       <string key="NSTitle">Show All</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="849004068">
+                                                                       <reference key="NSMenu" ref="276135462"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="938987619">
+                                                                       <reference key="NSMenu" ref="276135462"/>
+                                                                       <string key="NSTitle">Quit Angband</string>
+                                                                       <string key="NSKeyEquiv">q</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                       </array>
+                                                       <string key="NSName">_NSAppleMenu</string>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="911133406">
+                                               <reference key="NSMenu" ref="192124135"/>
+                                               <string key="NSTitle">File</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSKeyEquivModMask">1048576</int>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="433757408"/>
+                                               <reference key="NSMixedImage" ref="336434334"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <object class="NSMenu" key="NSSubmenu" id="285202175">
+                                                       <object class="NSMutableString" key="NSTitle">
+                                                               <characters key="NS.bytes">File</characters>
+                                                       </object>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="608499362">
+                                                                       <reference key="NSMenu" ref="285202175"/>
+                                                                       <string key="NSTitle">New</string>
+                                                                       <string key="NSKeyEquiv">n</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="620490283">
+                                                                       <reference key="NSMenu" ref="285202175"/>
+                                                                       <string key="NSTitle">Open…</string>
+                                                                       <string key="NSKeyEquiv">o</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="631772514">
+                                                                       <reference key="NSMenu" ref="285202175"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="962826103">
+                                                                       <reference key="NSMenu" ref="285202175"/>
+                                                                       <string key="NSTitle">Save</string>
+                                                                       <string key="NSKeyEquiv">s</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                       </array>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="1005222062">
+                                               <reference key="NSMenu" ref="192124135"/>
+                                               <string key="NSTitle">Settings</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSKeyEquivModMask">1048576</int>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="433757408"/>
+                                               <reference key="NSMixedImage" ref="336434334"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <object class="NSMenu" key="NSSubmenu" id="910893778">
+                                                       <string key="NSTitle">Settings</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="804246529">
+                                                                       <reference key="NSMenu" ref="910893778"/>
+                                                                       <string key="NSTitle">Edit Font</string>
+                                                                       <string key="NSKeyEquiv">t</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="351341973">
+                                                                       <reference key="NSMenu" ref="910893778"/>
+                                                                       <string key="NSTitle">Graphics</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                                       <string key="NSAction">submenuAction:</string>
+                                                                       <object class="NSMenu" key="NSSubmenu" id="322993771">
+                                                                               <string key="NSTitle">Graphics</string>
+                                                                               <array class="NSMutableArray" key="NSMenuItems"/>
+                                                                       </object>
+                                                               </object>
+                                                       </array>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="595080558">
+                                               <reference key="NSMenu" ref="192124135"/>
+                                               <string key="NSTitle">Animation speed</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSKeyEquivModMask">1048576</int>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="433757408"/>
+                                               <reference key="NSMixedImage" ref="336434334"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <int key="NSTag">150</int>
+                                               <object class="NSMenu" key="NSSubmenu" id="599982297">
+                                                       <string key="NSTitle">Animation speed</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="216525854">
+                                                                       <reference key="NSMenu" ref="599982297"/>
+                                                                       <string key="NSTitle">Infinite (no animation)</string>
+                                                                       <string key="NSKeyEquiv">1</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="678569181">
+                                                                       <reference key="NSMenu" ref="599982297"/>
+                                                                       <string key="NSTitle">60 fps</string>
+                                                                       <string key="NSKeyEquiv">2</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                                       <int key="NSTag">60</int>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="53675809">
+                                                                       <reference key="NSMenu" ref="599982297"/>
+                                                                       <string key="NSTitle">50 fps</string>
+                                                                       <string key="NSKeyEquiv">3</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                                       <int key="NSTag">50</int>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="582052947">
+                                                                       <reference key="NSMenu" ref="599982297"/>
+                                                                       <string key="NSTitle">40 fps</string>
+                                                                       <string key="NSKeyEquiv">4</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                                       <int key="NSTag">40</int>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="204807655">
+                                                                       <reference key="NSMenu" ref="599982297"/>
+                                                                       <string key="NSTitle">30 fps</string>
+                                                                       <string key="NSKeyEquiv">5</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                                       <int key="NSTag">30</int>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="748869944">
+                                                                       <reference key="NSMenu" ref="599982297"/>
+                                                                       <string key="NSTitle">20 fps</string>
+                                                                       <string key="NSKeyEquiv">6</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                                       <int key="NSTag">20</int>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="360181261">
+                                                                       <reference key="NSMenu" ref="599982297"/>
+                                                                       <string key="NSTitle">10 fps</string>
+                                                                       <string key="NSKeyEquiv">7</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                                       <int key="NSTag">10</int>
+                                                               </object>
+                                                       </array>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="755563077">
+                                               <reference key="NSMenu" ref="192124135"/>
+                                               <string key="NSTitle">Command</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="433757408"/>
+                                               <reference key="NSMixedImage" ref="336434334"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <object class="NSMenu" key="NSSubmenu" id="981663387">
+                                                       <string key="NSTitle">Command</string>
+                                                       <array class="NSMutableArray" key="NSMenuItems"/>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="586169331">
+                                               <reference key="NSMenu" ref="192124135"/>
+                                               <string key="NSTitle">Window</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSKeyEquivModMask">1048576</int>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="433757408"/>
+                                               <reference key="NSMixedImage" ref="336434334"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <object class="NSMenu" key="NSSubmenu" id="695195135">
+                                                       <object class="NSMutableString" key="NSTitle">
+                                                               <characters key="NS.bytes">Window</characters>
+                                                       </object>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="768970000">
+                                                                       <reference key="NSMenu" ref="695195135"/>
+                                                                       <string key="NSTitle">Minimize</string>
+                                                                       <string key="NSKeyEquiv">m</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="1000229087">
+                                                                       <reference key="NSMenu" ref="695195135"/>
+                                                                       <string key="NSTitle">Zoom</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="89715064">
+                                                                       <reference key="NSMenu" ref="695195135"/>
+                                                                       <bool key="NSIsDisabled">YES</bool>
+                                                                       <bool key="NSIsSeparator">YES</bool>
+                                                                       <string key="NSTitle"/>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                               <object class="NSMenuItem" id="1006865525">
+                                                                       <reference key="NSMenu" ref="695195135"/>
+                                                                       <string key="NSTitle">Bring All to Front</string>
+                                                                       <string key="NSKeyEquiv"/>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                       </array>
+                                                       <string key="NSName">_NSWindowsMenu</string>
+                                               </object>
+                                       </object>
+                                       <object class="NSMenuItem" id="624783398">
+                                               <reference key="NSMenu" ref="192124135"/>
+                                               <string key="NSTitle">Help</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSKeyEquivModMask">1048576</int>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="433757408"/>
+                                               <reference key="NSMixedImage" ref="336434334"/>
+                                               <string key="NSAction">submenuAction:</string>
+                                               <object class="NSMenu" key="NSSubmenu" id="851872137">
+                                                       <object class="NSMutableString" key="NSTitle">
+                                                               <characters key="NS.bytes">Help</characters>
+                                                       </object>
+                                                       <array class="NSMutableArray" key="NSMenuItems">
+                                                               <object class="NSMenuItem" id="318670906">
+                                                                       <reference key="NSMenu" ref="851872137"/>
+                                                                       <string key="NSTitle">Angband Help</string>
+                                                                       <string key="NSKeyEquiv">?</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <int key="NSMnemonicLoc">2147483647</int>
+                                                                       <reference key="NSOnImage" ref="433757408"/>
+                                                                       <reference key="NSMixedImage" ref="336434334"/>
+                                                               </object>
+                                                       </array>
+                                               </object>
+                                       </object>
+                               </array>
+                               <string key="NSName">_NSMainMenu</string>
+                       </object>
+                       <object class="NSCustomObject" id="27347545">
+                               <string key="NSClassName">AngbandAppDelegate</string>
+                       </object>
+               </array>
+               <object class="IBObjectContainer" key="IBDocument.Objects">
+                       <array class="NSMutableArray" key="connectionRecords">
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">terminate:</string>
+                                               <reference key="source" ref="1033716387"/>
+                                               <reference key="destination" ref="938987619"/>
+                                       </object>
+                                       <int key="connectionID">139</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">orderFrontStandardAboutPanel:</string>
+                                               <reference key="source" ref="1033716387"/>
+                                               <reference key="destination" ref="38615067"/>
+                                       </object>
+                                       <int key="connectionID">142</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">hideOtherApplications:</string>
+                                               <reference key="source" ref="1033716387"/>
+                                               <reference key="destination" ref="316901192"/>
+                                       </object>
+                                       <int key="connectionID">146</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">hide:</string>
+                                               <reference key="source" ref="1033716387"/>
+                                               <reference key="destination" ref="757690975"/>
+                                       </object>
+                                       <int key="connectionID">152</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">unhideAllApplications:</string>
+                                               <reference key="source" ref="1033716387"/>
+                                               <reference key="destination" ref="538675488"/>
+                                       </object>
+                                       <int key="connectionID">153</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">delegate</string>
+                                               <reference key="source" ref="1033716387"/>
+                                               <reference key="destination" ref="27347545"/>
+                                       </object>
+                                       <int key="connectionID">266</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performMiniaturize:</string>
+                                               <reference key="source" ref="515537150"/>
+                                               <reference key="destination" ref="768970000"/>
+                                       </object>
+                                       <int key="connectionID">37</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">arrangeInFront:</string>
+                                               <reference key="source" ref="515537150"/>
+                                               <reference key="destination" ref="1006865525"/>
+                                       </object>
+                                       <int key="connectionID">39</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">showHelp:</string>
+                                               <reference key="source" ref="515537150"/>
+                                               <reference key="destination" ref="318670906"/>
+                                       </object>
+                                       <int key="connectionID">122</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performZoom:</string>
+                                               <reference key="source" ref="515537150"/>
+                                               <reference key="destination" ref="1000229087"/>
+                                       </object>
+                                       <int key="connectionID">240</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">editFont:</string>
+                                               <reference key="source" ref="515537150"/>
+                                               <reference key="destination" ref="804246529"/>
+                                       </object>
+                                       <int key="connectionID">278</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">setRefreshRate:</string>
+                                               <reference key="source" ref="515537150"/>
+                                               <reference key="destination" ref="216525854"/>
+                                       </object>
+                                       <int key="connectionID">294</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">setRefreshRate:</string>
+                                               <reference key="source" ref="515537150"/>
+                                               <reference key="destination" ref="678569181"/>
+                                       </object>
+                                       <int key="connectionID">296</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">setRefreshRate:</string>
+                                               <reference key="source" ref="515537150"/>
+                                               <reference key="destination" ref="53675809"/>
+                                       </object>
+                                       <int key="connectionID">297</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">setRefreshRate:</string>
+                                               <reference key="source" ref="515537150"/>
+                                               <reference key="destination" ref="582052947"/>
+                                       </object>
+                                       <int key="connectionID">298</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">setRefreshRate:</string>
+                                               <reference key="source" ref="515537150"/>
+                                               <reference key="destination" ref="204807655"/>
+                                       </object>
+                                       <int key="connectionID">299</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">setRefreshRate:</string>
+                                               <reference key="source" ref="515537150"/>
+                                               <reference key="destination" ref="748869944"/>
+                                       </object>
+                                       <int key="connectionID">300</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">setRefreshRate:</string>
+                                               <reference key="source" ref="515537150"/>
+                                               <reference key="destination" ref="360181261"/>
+                                       </object>
+                                       <int key="connectionID">301</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">delegate</string>
+                                               <reference key="source" ref="322993771"/>
+                                               <reference key="destination" ref="27347545"/>
+                                       </object>
+                                       <int key="connectionID">279</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">newGame:</string>
+                                               <reference key="source" ref="27347545"/>
+                                               <reference key="destination" ref="608499362"/>
+                                       </object>
+                                       <int key="connectionID">271</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">openGame:</string>
+                                               <reference key="source" ref="27347545"/>
+                                               <reference key="destination" ref="620490283"/>
+                                       </object>
+                                       <int key="connectionID">272</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">saveGame:</string>
+                                               <reference key="source" ref="27347545"/>
+                                               <reference key="destination" ref="962826103"/>
+                                       </object>
+                                       <int key="connectionID">343</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">commandMenu</string>
+                                               <reference key="source" ref="27347545"/>
+                                               <reference key="destination" ref="981663387"/>
+                                       </object>
+                                       <int key="connectionID">351</int>
+                               </object>
+                       </array>
+                       <object class="IBMutableOrderedSet" key="objectRecords">
+                               <array key="orderedObjects">
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">0</int>
+                                               <array key="object" id="0"/>
+                                               <reference key="children" ref="1045887612"/>
+                                               <nil key="parent"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-2</int>
+                                               <reference key="object" ref="1033716387"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">File's Owner</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-1</int>
+                                               <reference key="object" ref="515537150"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">First Responder</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">29</int>
+                                               <reference key="object" ref="192124135"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="586169331"/>
+                                                       <reference ref="688321870"/>
+                                                       <reference ref="911133406"/>
+                                                       <reference ref="624783398"/>
+                                                       <reference ref="1005222062"/>
+                                                       <reference ref="595080558"/>
+                                                       <reference ref="755563077"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">MainMenu</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">19</int>
+                                               <reference key="object" ref="586169331"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="695195135"/>
+                                               </array>
+                                               <reference key="parent" ref="192124135"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">24</int>
+                                               <reference key="object" ref="695195135"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="1006865525"/>
+                                                       <reference ref="768970000"/>
+                                                       <reference ref="89715064"/>
+                                                       <reference ref="1000229087"/>
+                                               </array>
+                                               <reference key="parent" ref="586169331"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">5</int>
+                                               <reference key="object" ref="1006865525"/>
+                                               <reference key="parent" ref="695195135"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">23</int>
+                                               <reference key="object" ref="768970000"/>
+                                               <reference key="parent" ref="695195135"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">92</int>
+                                               <reference key="object" ref="89715064"/>
+                                               <reference key="parent" ref="695195135"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">239</int>
+                                               <reference key="object" ref="1000229087"/>
+                                               <reference key="parent" ref="695195135"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">56</int>
+                                               <reference key="object" ref="688321870"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="276135462"/>
+                                               </array>
+                                               <reference key="parent" ref="192124135"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">57</int>
+                                               <reference key="object" ref="276135462"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="38615067"/>
+                                                       <reference ref="931707326"/>
+                                                       <reference ref="622427103"/>
+                                                       <reference ref="757690975"/>
+                                                       <reference ref="938987619"/>
+                                                       <reference ref="698213426"/>
+                                                       <reference ref="478453786"/>
+                                                       <reference ref="316901192"/>
+                                                       <reference ref="849004068"/>
+                                                       <reference ref="538675488"/>
+                                                       <reference ref="428716132"/>
+                                               </array>
+                                               <reference key="parent" ref="688321870"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">58</int>
+                                               <reference key="object" ref="38615067"/>
+                                               <reference key="parent" ref="276135462"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">129</int>
+                                               <reference key="object" ref="931707326"/>
+                                               <reference key="parent" ref="276135462"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">131</int>
+                                               <reference key="object" ref="622427103"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="595688328"/>
+                                               </array>
+                                               <reference key="parent" ref="276135462"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">130</int>
+                                               <reference key="object" ref="595688328"/>
+                                               <reference key="parent" ref="622427103"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">134</int>
+                                               <reference key="object" ref="757690975"/>
+                                               <reference key="parent" ref="276135462"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">136</int>
+                                               <reference key="object" ref="938987619"/>
+                                               <reference key="parent" ref="276135462"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">143</int>
+                                               <reference key="object" ref="698213426"/>
+                                               <reference key="parent" ref="276135462"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">144</int>
+                                               <reference key="object" ref="478453786"/>
+                                               <reference key="parent" ref="276135462"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">145</int>
+                                               <reference key="object" ref="316901192"/>
+                                               <reference key="parent" ref="276135462"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">149</int>
+                                               <reference key="object" ref="849004068"/>
+                                               <reference key="parent" ref="276135462"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">150</int>
+                                               <reference key="object" ref="538675488"/>
+                                               <reference key="parent" ref="276135462"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">236</int>
+                                               <reference key="object" ref="428716132"/>
+                                               <reference key="parent" ref="276135462"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">83</int>
+                                               <reference key="object" ref="911133406"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="285202175"/>
+                                               </array>
+                                               <reference key="parent" ref="192124135"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">81</int>
+                                               <reference key="object" ref="285202175"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="620490283"/>
+                                                       <reference ref="631772514"/>
+                                                       <reference ref="608499362"/>
+                                                       <reference ref="962826103"/>
+                                               </array>
+                                               <reference key="parent" ref="911133406"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">72</int>
+                                               <reference key="object" ref="620490283"/>
+                                               <reference key="parent" ref="285202175"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">79</int>
+                                               <reference key="object" ref="631772514"/>
+                                               <reference key="parent" ref="285202175"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">82</int>
+                                               <reference key="object" ref="608499362"/>
+                                               <reference key="parent" ref="285202175"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">103</int>
+                                               <reference key="object" ref="624783398"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="851872137"/>
+                                               </array>
+                                               <reference key="parent" ref="192124135"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">106</int>
+                                               <reference key="object" ref="851872137"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="318670906"/>
+                                               </array>
+                                               <reference key="parent" ref="624783398"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">111</int>
+                                               <reference key="object" ref="318670906"/>
+                                               <reference key="parent" ref="851872137"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">252</int>
+                                               <reference key="object" ref="1005222062"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="910893778"/>
+                                               </array>
+                                               <reference key="parent" ref="192124135"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">253</int>
+                                               <reference key="object" ref="910893778"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="351341973"/>
+                                                       <reference ref="804246529"/>
+                                               </array>
+                                               <reference key="parent" ref="1005222062"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">256</int>
+                                               <reference key="object" ref="351341973"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="322993771"/>
+                                               </array>
+                                               <reference key="parent" ref="910893778"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">257</int>
+                                               <reference key="object" ref="322993771"/>
+                                               <array class="NSMutableArray" key="children"/>
+                                               <reference key="parent" ref="351341973"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">275</int>
+                                               <reference key="object" ref="804246529"/>
+                                               <reference key="parent" ref="910893778"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">284</int>
+                                               <reference key="object" ref="595080558"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="599982297"/>
+                                               </array>
+                                               <reference key="parent" ref="192124135"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">285</int>
+                                               <reference key="object" ref="599982297"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="216525854"/>
+                                                       <reference ref="678569181"/>
+                                                       <reference ref="53675809"/>
+                                                       <reference ref="582052947"/>
+                                                       <reference ref="204807655"/>
+                                                       <reference ref="748869944"/>
+                                                       <reference ref="360181261"/>
+                                               </array>
+                                               <reference key="parent" ref="595080558"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">287</int>
+                                               <reference key="object" ref="216525854"/>
+                                               <reference key="parent" ref="599982297"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">288</int>
+                                               <reference key="object" ref="678569181"/>
+                                               <reference key="parent" ref="599982297"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">289</int>
+                                               <reference key="object" ref="53675809"/>
+                                               <reference key="parent" ref="599982297"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">290</int>
+                                               <reference key="object" ref="582052947"/>
+                                               <reference key="parent" ref="599982297"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">291</int>
+                                               <reference key="object" ref="204807655"/>
+                                               <reference key="parent" ref="599982297"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">292</int>
+                                               <reference key="object" ref="748869944"/>
+                                               <reference key="parent" ref="599982297"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">293</int>
+                                               <reference key="object" ref="360181261"/>
+                                               <reference key="parent" ref="599982297"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">265</int>
+                                               <reference key="object" ref="27347545"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">AngbandAppDelegate</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">-3</int>
+                                               <reference key="object" ref="848297368"/>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">Application</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">342</int>
+                                               <reference key="object" ref="962826103"/>
+                                               <reference key="parent" ref="285202175"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">346</int>
+                                               <reference key="object" ref="755563077"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="981663387"/>
+                                               </array>
+                                               <reference key="parent" ref="192124135"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">347</int>
+                                               <reference key="object" ref="981663387"/>
+                                               <array class="NSMutableArray" key="children"/>
+                                               <reference key="parent" ref="755563077"/>
+                                       </object>
+                               </array>
+                       </object>
+                       <dictionary class="NSMutableDictionary" key="flattenedProperties">
+                               <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="103.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="106.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="111.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="129.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="130.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="131.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="134.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="136.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="143.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="144.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="145.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="149.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="150.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="19.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="23.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="236.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="239.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="24.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="252.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="253.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="256.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="257.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="265.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="275.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="284.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="285.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="287.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="288.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="289.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="29.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="290.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="291.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="292.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="293.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="342.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="346.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="347.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="5.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="58.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="72.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="79.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="81.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="82.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="83.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="92.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                       </dictionary>
+                       <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+                       <nil key="activeLocalization"/>
+                       <dictionary class="NSMutableDictionary" key="localizations"/>
+                       <nil key="sourceID"/>
+                       <int key="maxID">351</int>
+               </object>
+               <object class="IBClassDescriber" key="IBDocument.Classes">
+                       <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+                               <object class="IBPartialClassDescription">
+                                       <string key="className">AngbandAppDelegate</string>
+                                       <string key="superclassName">NSObject</string>
+                                       <dictionary class="NSMutableDictionary" key="actions">
+                                               <string key="editFont:">id</string>
+                                               <string key="newGame:">id</string>
+                                               <string key="openGame:">id</string>
+                                               <string key="saveGame:">id</string>
+                                               <string key="setRefreshRate:">NSMenuItem</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="actionInfosByName">
+                                               <object class="IBActionInfo" key="editFont:">
+                                                       <string key="name">editFont:</string>
+                                                       <string key="candidateClassName">id</string>
+                                               </object>
+                                               <object class="IBActionInfo" key="newGame:">
+                                                       <string key="name">newGame:</string>
+                                                       <string key="candidateClassName">id</string>
+                                               </object>
+                                               <object class="IBActionInfo" key="openGame:">
+                                                       <string key="name">openGame:</string>
+                                                       <string key="candidateClassName">id</string>
+                                               </object>
+                                               <object class="IBActionInfo" key="saveGame:">
+                                                       <string key="name">saveGame:</string>
+                                                       <string key="candidateClassName">id</string>
+                                               </object>
+                                               <object class="IBActionInfo" key="setRefreshRate:">
+                                                       <string key="name">setRefreshRate:</string>
+                                                       <string key="candidateClassName">NSMenuItem</string>
+                                               </object>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="outlets">
+                                               <string key="commandMenu">NSMenu</string>
+                                               <string key="terminalsMenu">NSMenu</string>
+                                       </dictionary>
+                                       <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <object class="IBToOneOutletInfo" key="commandMenu">
+                                                       <string key="name">commandMenu</string>
+                                                       <string key="candidateClassName">NSMenu</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="terminalsMenu">
+                                                       <string key="name">terminalsMenu</string>
+                                                       <string key="candidateClassName">NSMenu</string>
+                                               </object>
+                                       </dictionary>
+                                       <object class="IBClassDescriptionSource" key="sourceIdentifier">
+                                               <string key="majorKey">IBProjectSource</string>
+                                               <string key="minorKey">./Classes/AngbandAppDelegate.h</string>
+                                       </object>
+                               </object>
+                       </array>
+               </object>
+               <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
+               <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
+                       <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
+                       <integer value="1060" key="NS.object.0"/>
+               </object>
+               <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+               <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+                       <string key="NSMenuCheckmark">{11, 11}</string>
+                       <string key="NSMenuMixedState">{10, 3}</string>
+               </dictionary>
+       </data>
+</archive>
diff --git a/src/cocoa/English.lproj/MainMenu.nib/keyedobjects.nib b/src/cocoa/English.lproj/MainMenu.nib/keyedobjects.nib
new file mode 100644 (file)
index 0000000..8852ca9
Binary files /dev/null and b/src/cocoa/English.lproj/MainMenu.nib/keyedobjects.nib differ
diff --git a/src/cocoa/Save.icns b/src/cocoa/Save.icns
new file mode 100644 (file)
index 0000000..9374c4a
Binary files /dev/null and b/src/cocoa/Save.icns differ
diff --git a/src/main-cocoa.m b/src/main-cocoa.m
new file mode 100644 (file)
index 0000000..57dc7e1
--- /dev/null
@@ -0,0 +1,3315 @@
+/* File: main-cocoa.m */
+
+/*
+ * Copyright (c) 2011 Peter Ammon
+ *
+ * This work is free software; you can redistribute it and/or modify it
+ * under the terms of either:
+ *
+ * a) the GNU General Public License as published by the Free Software
+ *    Foundation, version 2, or
+ *
+ * b) the "Angband licence":
+ *    This software may be copied and distributed for educational, research,
+ *    and not for profit purposes provided that this copyright and statement
+ *    are included in all such copies.  Other copyrights may also apply.
+ */
+
+#include "angband.h"
+
+#if defined(MACH_O_CARBON)
+
+/* Default creator signature */
+#ifndef ANGBAND_CREATOR
+# define ANGBAND_CREATOR 'Heng'
+#endif
+
+/* Mac headers */
+#include <Cocoa/Cocoa.h>
+#include <Carbon/Carbon.h> // For keycodes
+
+static NSSize const AngbandScaleIdentity = {1.0, 1.0};
+static NSString * const AngbandDirectoryNameLib = @"lib";
+static NSString * const AngbandDirectoryNameBase = @"PosChengband";
+
+static NSString * const AngbandTerminalsDefaultsKey = @"Terminals";
+static NSString * const AngbandTerminalRowsDefaultsKey = @"Rows";
+static NSString * const AngbandTerminalColumnsDefaultsKey = @"Columns";
+static NSInteger const AngbandWindowMenuItemTagBase = 1000;
+static NSInteger const AngbandCommandMenuItemTagBase = 2000;
+
+/* We can blit to a large layer or image and then scale it down during live resize, which makes resizing much faster, at the cost of some image quality during resizing */
+#ifndef USE_LIVE_RESIZE_CACHE
+# define USE_LIVE_RESIZE_CACHE 1
+#endif
+
+/* Global defines etc from Angband 3.5-dev - NRM */
+#define ANGBAND_TERM_MAX 8
+/**
+ * Specifies what kind of thing a file is, when writing.  See file_open().
+ */
+typedef enum
+{
+        FTYPE_TEXT = 1,
+        FTYPE_SAVE,
+        FTYPE_RAW,
+        FTYPE_HTML
+} file_type;
+
+static bool new_game = TRUE;
+
+#define MAX_COLORS 256
+#define MSG_MAX SOUND_MAX
+
+/**
+ * Keyset mappings for various keys.
+ */
+#define ARROW_DOWN    0x80
+#define ARROW_LEFT    0x81
+#define ARROW_RIGHT   0x82
+#define ARROW_UP      0x83
+
+#define KC_F1         0x84
+#define KC_F2         0x85
+#define KC_F3         0x86
+#define KC_F4         0x87
+#define KC_F5         0x88
+#define KC_F6         0x89
+#define KC_F7         0x8A
+#define KC_F8         0x8B
+#define KC_F9         0x8C
+#define KC_F10        0x8D
+#define KC_F11        0x8E
+#define KC_F12        0x8F
+#define KC_F13        0x90
+#define KC_F14        0x91
+#define KC_F15        0x92
+
+#define KC_HELP       0x93
+#define KC_HOME       0x94
+#define KC_PGUP       0x95
+#define KC_END        0x96
+#define KC_PGDOWN     0x97
+#define KC_INSERT     0x98
+#define KC_PAUSE      0x99
+#define KC_BREAK      0x9a
+#define KC_BEGIN      0x9b
+#define KC_ENTER      0x9c /* ASCII \r */
+#define KC_TAB        0x9d /* ASCII \t */
+#define KC_DELETE     0x9e
+#define KC_BACKSPACE  0x9f /* ASCII \h */
+//#define ESCAPE        0xE000
+
+//OSType _ftype;
+//OSType _fcreator;
+
+/* End Angband stuff - NRM */
+
+/* Our command-fetching function */
+//static errr cocoa_get_cmd(cmd_context context, bool wait);
+
+
+/* Application defined event numbers */
+enum
+{
+    AngbandEventWakeup = 1
+};
+
+/* Redeclare some 10.7 constants and methods so we can build on 10.6 */
+enum
+{
+    Angband_NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7,
+    Angband_NSWindowCollectionBehaviorFullScreenAuxiliary = 1 << 8
+};
+
+@interface NSWindow (AngbandLionRedeclares)
+- (void)setRestorable:(BOOL)flag;
+@end
+
+/* Delay handling of pre-emptive "quit" event */
+static BOOL quit_when_ready = FALSE;
+
+/* Whether or not we allow sounds (only relevant for the screensaver, where the user can't configure it in-game) */
+static BOOL allow_sounds = YES;
+
+/* Set to indicate the game is over and we can quit without delay */
+static Boolean game_is_finished = FALSE;
+
+/* Our frames per second (e.g. 60). A value of 0 means unthrottled. */
+static int frames_per_second;
+
+/* Function to get the default font */
+static NSFont *default_font;
+
+@class AngbandView;
+
+/* The max number of glyphs we support */
+#define GLYPH_COUNT 256
+
+/* An AngbandContext represents a logical Term (i.e. what Angband thinks is a window). This typically maps to one NSView, but may map to more than one NSView (e.g. the Test and real screen saver view). */
+@interface AngbandContext : NSObject <NSWindowDelegate>
+{
+@public
+    
+    /* The Angband term */
+    term *terminal;
+    
+    /* Column and row cont, by default 80 x 24 */
+    size_t cols;
+    size_t rows;
+    
+    /* The size of the border between the window edge and the contents */
+    NSSize borderSize;
+    
+    /* Our array of views */
+    NSMutableArray *angbandViews;
+    
+    /* The buffered image */
+    CGLayerRef angbandLayer;
+    
+    /* The font of this context */
+    NSFont *angbandViewFont;
+    
+    /* If this context owns a window, here it is */
+    NSWindow *primaryWindow;
+    
+    /* "Glyph info": an array of the CGGlyphs and their widths corresponding to the above font. */
+    CGGlyph glyphArray[GLYPH_COUNT];
+    CGFloat glyphWidths[GLYPH_COUNT];
+    
+    /* The size of one tile */
+    NSSize tileSize;
+    
+    /* Font's descender */
+    CGFloat fontDescender;
+    
+    /* Whether we are currently in live resize, which affects how big we render our image */
+    int inLiveResize;
+    
+    /* Last time we drew, so we can throttle drawing */
+    CFAbsoluteTime lastRefreshTime;
+    
+    /* To address subpixel rendering overdraw problems, we cache all the characters and attributes we're told to draw */
+    wchar_t *charOverdrawCache;
+    int *attrOverdrawCache;
+
+@private
+
+    BOOL _hasSubwindowFlags;
+}
+
+@property (nonatomic, assign) BOOL hasSubwindowFlags;
+
+- (void)drawRect:(NSRect)rect inView:(NSView *)view;
+
+/* Called at initialization to set the term */
+- (void)setTerm:(term *)t;
+
+/* Called when the context is going down. */
+- (void)dispose;
+
+/* Returns the size of the image. */
+- (NSSize)imageSize;
+
+/* Return the rect for a tile at given coordinates. */
+- (NSRect)rectInImageForTileAtX:(int)x Y:(int)y;
+
+/* Draw the given wide character into the given tile rect. */
+- (void)drawWChar:(wchar_t)wchar inRect:(NSRect)tile;
+
+/* Locks focus on the Angband image, and scales the CTM appropriately. */
+- (CGContextRef)lockFocus;
+
+/* Locks focus on the Angband image but does NOT scale the CTM. Appropriate for drawing hairlines. */
+- (CGContextRef)lockFocusUnscaled;
+
+/* Unlocks focus. */
+- (void)unlockFocus;
+
+/* Returns the primary window for this angband context, creating it if necessary */
+- (NSWindow *)makePrimaryWindow;
+
+/* Called to add a new Angband view */
+- (void)addAngbandView:(AngbandView *)view;
+
+/* Make the context aware that one of its views changed size */
+- (void)angbandViewDidScale:(AngbandView *)view;
+
+/* Handle becoming the main window */
+- (void)windowDidBecomeMain:(NSNotification *)notification;
+
+/* Order the context's primary window frontmost */
+- (void)orderFront;
+
+/* Order the context's primary window out */
+- (void)orderOut;
+
+/* Return whether the context's primary window is ordered in or not */
+- (BOOL)isOrderedIn;
+
+/* Return whether the context's primary window is key */
+- (BOOL)isMainWindow;
+
+/* Invalidate the whole image */
+- (void)setNeedsDisplay:(BOOL)val;
+
+/* Invalidate part of the image, with the rect expressed in base coordinates */
+- (void)setNeedsDisplayInBaseRect:(NSRect)rect;
+
+/* Display (flush) our Angband views */
+- (void)displayIfNeeded;
+
+/* Called from the view to indicate that it is starting or ending live resize */
+- (void)viewWillStartLiveResize:(AngbandView *)view;
+- (void)viewDidEndLiveResize:(AngbandView *)view;
+
+/* Class methods */
+
+/* Begins an Angband game. This is the entry point for starting off. */
++ (void)beginGame;
+
+/* Ends an Angband game. */
++ (void)endGame;
+
+/* Internal method */
+- (AngbandView *)activeView;
+
+@end
+
+/**
+ *  Generate a mask for the subwindow flags. The mask is just a safety check to make sure that our windows show and hide as expected.
+ *  This function allows for future changes to the set of flags without needed to update it here (unless the underlying types change).
+ */
+u32b AngbandMaskForValidSubwindowFlags(void)
+{
+    int maxBits = 16;
+    u32b mask = 0;
+
+    for( int i = 0; i < maxBits; i++ )
+    {
+        if( window_flag_desc[i] != NULL )
+        {
+            mask |= (1 << i);
+        }
+    }
+
+    return mask;
+}
+
+/**
+ *  Check for changes in the subwindow flags and update window visibility. This seems to be called for every user event, so we don't
+ *  want to do any unnecessary hiding or showing of windows.
+ */
+static void AngbandUpdateWindowVisibility(void)
+{
+    // because this function is called frequently, we'll make the mask static. it doesn't change between calls, since the flags themselves are hardcoded.
+    static u32b validWindowFlagsMask = 0;
+
+    if( validWindowFlagsMask == 0 )
+    {
+        validWindowFlagsMask = AngbandMaskForValidSubwindowFlags();
+    }
+
+    // loop through all of the subwindows and see if there is a change in the flags. if so, show or hide the corresponding window.
+    // we don't care about the flags themselves; we just want to know if any are set.
+    for( int i = 1; i < ANGBAND_TERM_MAX; i++ )
+    {
+        AngbandContext *angbandContext = angband_term[i]->data;
+
+        if( angbandContext == nil )
+        {
+            continue;
+        }
+
+        BOOL termHasSubwindowFlags = ((window_flag[i] & validWindowFlagsMask) > 0);
+
+        if( angbandContext.hasSubwindowFlags && !termHasSubwindowFlags )
+        {
+            [angbandContext->primaryWindow close];
+            angbandContext.hasSubwindowFlags = NO;
+        }
+        else if( !angbandContext.hasSubwindowFlags && termHasSubwindowFlags )
+        {
+            [angbandContext->primaryWindow orderFront: nil];
+            angbandContext.hasSubwindowFlags = YES;
+        }
+    }
+
+    // make the main window key so that user events go to the right spot
+    AngbandContext *mainWindow = angband_term[0]->data;
+    [mainWindow->primaryWindow makeKeyAndOrderFront: nil];
+}
+
+/* To indicate that a grid element contains a picture, we store 0xFFFF. */
+#define NO_OVERDRAW ((wchar_t)(0xFFFF))
+
+/* Here is some support for rounding to pixels in a scaled context */
+static double push_pixel(double pixel, double scale, BOOL increase)
+{
+    double scaledPixel = pixel * scale;
+    /* Have some tolerance! */
+    double roundedPixel = round(scaledPixel);
+    if (fabs(roundedPixel - scaledPixel) <= .0001)
+    {
+        scaledPixel = roundedPixel;
+    }
+    else
+    {
+        scaledPixel = (increase ? ceil : floor)(scaledPixel);
+    }
+    return scaledPixel / scale;
+}
+
+/* Descriptions of how to "push pixels" in a given rect to integralize. For example, PUSH_LEFT means that we round expand the left edge if set, otherwise we shrink it. */
+enum
+{
+    PUSH_LEFT = 0x1,
+    PUSH_RIGHT = 0x2,
+    PUSH_BOTTOM = 0x4,
+    PUSH_TOP = 0x8
+};
+
+/* Return a rect whose border is in the "cracks" between tiles */
+static NSRect crack_rect(NSRect rect, NSSize scale, unsigned pushOptions)
+{
+    double rightPixel = push_pixel(NSMaxX(rect), scale.width, !! (pushOptions & PUSH_RIGHT));
+    double topPixel = push_pixel(NSMaxY(rect), scale.height, !! (pushOptions & PUSH_TOP));
+    double leftPixel = push_pixel(NSMinX(rect), scale.width, ! (pushOptions & PUSH_LEFT));
+    double bottomPixel = push_pixel(NSMinY(rect), scale.height, ! (pushOptions & PUSH_BOTTOM));
+    return NSMakeRect(leftPixel, bottomPixel, rightPixel - leftPixel, topPixel - bottomPixel);    
+}
+
+/* Returns the pixel push options (describing how we round) for the tile at a given index. Currently it's pretty uniform! */
+static unsigned push_options(unsigned x, unsigned y)
+{
+    return PUSH_TOP | PUSH_LEFT;
+}
+
+/*
+ * Graphics support
+ */
+
+/*
+ * The tile image
+ */
+//static CGImageRef pict_image;
+
+/*
+ * Numbers of rows and columns in a tileset,
+ * calculated by the PICT/PNG loading code
+ */
+//static int pict_cols = 0;
+//static int pict_rows = 0;
+
+/*
+ * Value used to signal that we using ASCII, not graphical tiles.
+ */ 
+#define GRAF_MODE_NONE 0
+
+/*
+ * Requested graphics mode (as a grafID).
+ * The current mode is stored in current_graphics_mode.
+ */
+static int graf_mode_req = 0;
+
+/*
+ * Helper function to check the various ways that graphics can be enabled, guarding against NULL
+ */
+static BOOL graphics_are_enabled(void)
+{
+    return GRAPHICS_NONE;
+}
+
+/*
+ * Hack -- game in progress
+ */
+static Boolean game_in_progress = FALSE;
+
+
+#pragma mark Prototypes
+static void wakeup_event_loop(void);
+static void hook_plog(const char *str);
+static void hook_quit(const char * str);
+static void load_prefs(void);
+static void load_sounds(void);
+static void init_windows(void);
+static void handle_open_when_ready(void);
+//static void play_sound(int event);
+static BOOL check_events(int wait);
+//static void cocoa_file_open_hook(const char *path, file_type ftype);
+//static bool cocoa_get_file(const char *suggested_name, char *path, size_t len);
+static BOOL send_event(NSEvent *event);
+static void record_current_savefile(void);
+
+/*
+ * Available values for 'wait'
+ */
+#define CHECK_EVENTS_DRAIN -1
+#define CHECK_EVENTS_NO_WAIT   0
+#define CHECK_EVENTS_WAIT 1
+
+
+/* Methods for getting the appropriate NSUserDefaults */
+@interface NSUserDefaults (AngbandDefaults)
++ (NSUserDefaults *)angbandDefaults;
+@end
+
+@implementation NSUserDefaults (AngbandDefaults)
++ (NSUserDefaults *)angbandDefaults
+{
+    return [NSUserDefaults standardUserDefaults];
+}
+@end
+
+/* Methods for pulling images out of the Angband bundle (which may be separate from the current bundle in the case of a screensaver */
+@interface NSImage (AngbandImages)
++ (NSImage *)angbandImage:(NSString *)name;
+@end
+
+/* The NSView subclass that draws our Angband image */
+@interface AngbandView : NSView
+{
+    IBOutlet AngbandContext *angbandContext;
+}
+
+- (void)setAngbandContext:(AngbandContext *)context;
+- (AngbandContext *)angbandContext;
+
+@end
+
+@implementation NSImage (AngbandImages)
+
+/* Returns an image in the resource directoy of the bundle containing the Angband view class. */
++ (NSImage *)angbandImage:(NSString *)name
+{
+    NSBundle *bundle = [NSBundle bundleForClass:[AngbandView class]];
+    NSString *path = [bundle pathForImageResource:name];
+    NSImage *result;
+    if (path) result = [[[NSImage alloc] initByReferencingFile:path] autorelease];
+    else result = nil;
+    return result;
+}
+
+@end
+
+
+@implementation AngbandContext
+
+@synthesize hasSubwindowFlags=_hasSubwindowFlags;
+
+- (NSFont *)selectionFont
+{
+    return angbandViewFont;
+}
+
+- (BOOL)useLiveResizeOptimization
+{
+    /* If we have graphics turned off, text rendering is fast enough that we don't need to use a live resize optimization. Note here we are depending on current_graphics_mode being NULL when in text mode. */
+    return inLiveResize && graphics_are_enabled();
+}
+
+- (NSSize)baseSize
+{
+    /* We round the base size down. If we round it up, I believe we may end up with pixels that nobody "owns" that may accumulate garbage. In general rounding down is harmless, because any lost pixels may be sopped up by the border. */
+    return NSMakeSize(floor(cols * tileSize.width + 2 * borderSize.width), floor(rows * tileSize.height + 2 * borderSize.height));
+}
+
+// qsort-compatible compare function for CGSizes
+static int compare_advances(const void *ap, const void *bp)
+{
+    const CGSize *a = ap, *b = bp;
+    return (a->width > b->width) - (a->width < b->width);
+}
+
+- (void)updateGlyphInfo
+{
+    // Update glyphArray and glyphWidths
+    NSFont *screenFont = [angbandViewFont screenFont];
+
+    // Generate a string containing each MacRoman character
+    unsigned char latinString[GLYPH_COUNT];
+    size_t i;
+    for (i=0; i < GLYPH_COUNT; i++) latinString[i] = (unsigned char)i;
+    
+    // Turn that into unichar. Angband uses ISO Latin 1.
+    unichar unicharString[GLYPH_COUNT] = {0};
+    NSString *allCharsString = [[NSString alloc] initWithBytes:latinString length:sizeof latinString encoding:NSISOLatin1StringEncoding];
+    [allCharsString getCharacters:unicharString range:NSMakeRange(0, MIN(GLYPH_COUNT, [allCharsString length]))];
+    [allCharsString autorelease];
+    
+    // Get glyphs
+    memset(glyphArray, 0, sizeof glyphArray);
+    CTFontGetGlyphsForCharacters((CTFontRef)screenFont, unicharString, glyphArray, GLYPH_COUNT);
+    
+    // Get advances. Record the max advance.
+    CGSize advances[GLYPH_COUNT] = {};
+    CTFontGetAdvancesForGlyphs((CTFontRef)screenFont, kCTFontHorizontalOrientation, glyphArray, advances, GLYPH_COUNT);
+    for (i=0; i < GLYPH_COUNT; i++) {
+        glyphWidths[i] = advances[i].width;
+    }
+    
+    // For good non-mono-font support, use the median advance. Start by sorting all advances.
+    qsort(advances, GLYPH_COUNT, sizeof *advances, compare_advances);
+    
+    // Skip over any initially empty run
+    size_t startIdx;
+    for (startIdx = 0; startIdx < GLYPH_COUNT; startIdx++)
+    {
+        if (advances[startIdx].width > 0) break;
+    }
+    
+    // Pick the center to find the median
+    CGFloat medianAdvance = 0;
+    if (startIdx < GLYPH_COUNT)
+    { // In case we have all zero advances for some reason
+        medianAdvance = advances[(startIdx + GLYPH_COUNT)/2].width;
+    }
+    
+    // Record the descender
+    fontDescender = [screenFont descender];
+    
+    // Record the tile size. Note that these are typically fractional values - which seems sketchy, but we end up scaling the heck out of our view anyways, so it seems to not matter.
+    tileSize.width = medianAdvance;
+    tileSize.height = [screenFont ascender] - [screenFont descender];
+}
+
+- (void)updateImage
+{
+    NSSize size = NSMakeSize(1, 1);
+    
+    AngbandView *activeView = [self activeView];
+    if (activeView)
+    {
+        /* If we are in live resize, draw as big as the screen, so we can scale nicely to any size. If we are not in live resize, then use the bounds of the active view. */
+        NSScreen *screen;
+        if ([self useLiveResizeOptimization] && (screen = [[activeView window] screen]) != NULL)
+        {
+            size = [screen frame].size;
+        }
+        else
+        {
+            size = [activeView bounds].size;
+        }
+    }
+    
+    size.width = fmax(1, ceil(size.width));
+    size.height = fmax(1, ceil(size.height));
+    
+    CGLayerRelease(angbandLayer);
+    
+    // make a bitmap context as an example for our layer
+    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
+    CGContextRef exampleCtx = CGBitmapContextCreate(NULL, 1, 1, 8 /* bits per component */, 48 /* bytesPerRow */, cs, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host);
+    CGColorSpaceRelease(cs);
+    angbandLayer = CGLayerCreateWithContext(exampleCtx, *(CGSize *)&size, NULL);
+    CFRelease(exampleCtx);
+
+    [self lockFocus];
+    [[NSColor blackColor] set];
+    NSRectFill((NSRect){NSZeroPoint, [self baseSize]});
+    [self unlockFocus];
+}
+
+- (void)requestRedraw
+{
+    if (! self->terminal) return;
+    
+    term *old = Term;
+    
+    /* Activate the term */
+    Term_activate(self->terminal);
+    
+    /* Redraw the contents */
+    Term_redraw();
+    
+    /* Flush the output */
+    Term_fresh();
+    
+    /* Restore the old term */
+    Term_activate(old);
+}
+
+- (void)setTerm:(term *)t
+{
+    terminal = t;
+}
+
+- (void)viewWillStartLiveResize:(AngbandView *)view
+{
+#if USE_LIVE_RESIZE_CACHE
+    if (inLiveResize < INT_MAX) inLiveResize++;
+    else [NSException raise:NSInternalInconsistencyException format:@"inLiveResize overflow"];
+    
+    if (inLiveResize == 1 && graphics_are_enabled())
+    {
+        [self updateImage];
+        
+        [self setNeedsDisplay:YES]; //we'll need to redisplay everything anyways, so avoid creating all those little redisplay rects
+        [self requestRedraw];
+    }
+#endif
+}
+
+- (void)viewDidEndLiveResize:(AngbandView *)view
+{
+#if USE_LIVE_RESIZE_CACHE
+    if (inLiveResize > 0) inLiveResize--;
+    else [NSException raise:NSInternalInconsistencyException format:@"inLiveResize underflow"];
+    
+    if (inLiveResize == 0 && graphics_are_enabled())
+    {
+        [self updateImage];
+        
+        [self setNeedsDisplay:YES]; //we'll need to redisplay everything anyways, so avoid creating all those little redisplay rects
+        [self requestRedraw];
+    }
+#endif
+}
+
+/* If we're trying to limit ourselves to a certain number of frames per second, then compute how long it's been since we last drew, and then wait until the next frame has passed. */
+- (void)throttle
+{
+    if (frames_per_second > 0)
+    {
+        CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
+        CFTimeInterval timeSinceLastRefresh = now - lastRefreshTime;
+        CFTimeInterval timeUntilNextRefresh = (1. / (double)frames_per_second) - timeSinceLastRefresh;
+        
+        if (timeUntilNextRefresh > 0)
+        {
+            usleep((unsigned long)(timeUntilNextRefresh * 1000000.));
+        }
+    }
+    lastRefreshTime = CFAbsoluteTimeGetCurrent();
+}
+
+- (void)drawWChar:(wchar_t)wchar inRect:(NSRect)tile
+{
+    CGContextRef ctx = [[NSGraphicsContext currentContext] graphicsPort];
+    CGFloat tileOffsetY = CTFontGetAscent( (CTFontRef)[angbandViewFont screenFont] );
+    CGFloat tileOffsetX = 0.0;
+    NSFont *screenFont = [angbandViewFont screenFont];
+    UniChar unicharString[2] = {(UniChar)wchar, 0};
+
+    // Get glyph and advance
+    CGGlyph thisGlyphArray[1] = { 0 };
+    CGSize advances[1] = { { 0, 0 } };
+    CTFontGetGlyphsForCharacters((CTFontRef)screenFont, unicharString, thisGlyphArray, 1);
+    CGGlyph glyph = thisGlyphArray[0];
+    CTFontGetAdvancesForGlyphs((CTFontRef)screenFont, kCTFontHorizontalOrientation, thisGlyphArray, advances, 1);
+    CGSize advance = advances[0];
+    
+    /* If our font is not monospaced, our tile width is deliberately not big enough for every character. In that event, if our glyph is too wide, we need to compress it horizontally. Compute the compression ratio. 1.0 means no compression. */
+    double compressionRatio;
+    if (advance.width <= NSWidth(tile))
+    {
+        /* Our glyph fits, so we can just draw it, possibly with an offset */
+        compressionRatio = 1.0;
+        tileOffsetX = (NSWidth(tile) - advance.width)/2;
+    }
+    else
+    {
+        /* Our glyph doesn't fit, so we'll have to compress it */
+        compressionRatio = NSWidth(tile) / advance.width;
+        tileOffsetX = 0;
+    }
+
+    
+    /* Now draw it */
+    CGAffineTransform textMatrix = CGContextGetTextMatrix(ctx);
+    CGFloat savedA = textMatrix.a;
+
+    /* Set the position */
+    textMatrix.tx = tile.origin.x + tileOffsetX;
+    textMatrix.ty = tile.origin.y + tileOffsetY;
+
+    /* Maybe squish it horizontally. */
+    if (compressionRatio != 1.)
+    {
+        textMatrix.a *= compressionRatio;
+    }
+
+    textMatrix = CGAffineTransformScale( textMatrix, 1.0, -1.0 );
+    CGContextSetTextMatrix(ctx, textMatrix);
+    CGContextShowGlyphsWithAdvances(ctx, &glyph, &CGSizeZero, 1);
+    
+    /* Restore the text matrix if we messed with the compression ratio */
+    if (compressionRatio != 1.)
+    {
+        textMatrix.a = savedA;
+        CGContextSetTextMatrix(ctx, textMatrix);
+    }
+
+    textMatrix = CGAffineTransformScale( textMatrix, 1.0, -1.0 );
+    CGContextSetTextMatrix(ctx, textMatrix);
+}
+
+/* Indication that we're redrawing everything, so get rid of the overdraw cache. */
+- (void)clearOverdrawCache
+{
+    memset(charOverdrawCache, 0, self->cols * self->rows * sizeof *charOverdrawCache);
+    memset(attrOverdrawCache, 0, self->cols * self->rows * sizeof *attrOverdrawCache);
+}
+
+/* Lock and unlock focus on our image or layer, setting up the CTM appropriately. */
+- (CGContextRef)lockFocusUnscaled
+{
+    /* Create an NSGraphicsContext representing this CGLayer */
+    CGContextRef ctx = CGLayerGetContext(angbandLayer);
+    NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithGraphicsPort:ctx flipped:NO];
+    [NSGraphicsContext saveGraphicsState];
+    [NSGraphicsContext setCurrentContext:context];
+    CGContextSaveGState(ctx);
+    return ctx;
+}
+
+- (void)unlockFocus
+{
+    /* Restore the graphics state */
+    CGContextRef ctx = [[NSGraphicsContext currentContext] graphicsPort];
+    CGContextRestoreGState(ctx);
+    [NSGraphicsContext restoreGraphicsState];
+}
+
+- (NSSize)imageSize
+{
+    /* Return the size of our layer */
+    CGSize result = CGLayerGetSize(angbandLayer);
+    return NSMakeSize(result.width, result.height);
+}
+
+- (CGContextRef)lockFocus
+{
+    return [self lockFocusUnscaled];
+}
+
+
+- (NSRect)rectInImageForTileAtX:(int)x Y:(int)y
+{
+    int flippedY = y;
+    return NSMakeRect(x * tileSize.width + borderSize.width, flippedY * tileSize.height + borderSize.height, tileSize.width, tileSize.height);
+}
+
+- (void)setSelectionFont:(NSFont*)font adjustTerminal: (BOOL)adjustTerminal
+{
+    /* Record the new font */
+    [font retain];
+    [angbandViewFont release];
+    angbandViewFont = font;
+    
+    /* Update our glyph info */
+    [self updateGlyphInfo];
+
+    if( adjustTerminal )
+    {
+        // adjust terminal to fit window with new font; save the new columns and rows since they could be changed
+        NSRect contentRect = [self->primaryWindow contentRectForFrameRect: [self->primaryWindow frame]];
+        [self resizeTerminalWithContentRect: contentRect saveToDefaults: YES];
+    }
+
+    /* Update our image */
+    [self updateImage];
+    
+    /* Clear our overdraw cache */
+    [self clearOverdrawCache];
+    
+    /* Get redrawn */
+    [self requestRedraw];
+}
+
+- (id)init
+{
+    if ((self = [super init]))
+    {
+        /* Default rows and cols */
+        self->cols = 80;
+        self->rows = 24;
+
+        /* Default border size */
+        self->borderSize = NSMakeSize(2, 2);
+
+        /* Allocate overdraw cache, unscanned and collectable. */
+        self->charOverdrawCache = NSAllocateCollectable(self->cols * self->rows *sizeof *charOverdrawCache, 0);
+        self->attrOverdrawCache = NSAllocateCollectable(self->cols * self->rows *sizeof *attrOverdrawCache, 0);
+        
+        /* Allocate our array of views */
+        angbandViews = [[NSMutableArray alloc] init];
+        
+        /* Make the image. Since we have no views, it'll just be a puny 1x1 image. */
+        [self updateImage];        
+    }
+    return self;
+}
+
+/* Destroy all the receiver's stuff. This is intended to be callable more than once. */
+- (void)dispose
+{
+    terminal = NULL;
+    
+    /* Disassociate ourselves from our angbandViews */
+    [angbandViews makeObjectsPerformSelector:@selector(setAngbandContext:) withObject:nil];
+    [angbandViews release];
+    angbandViews = nil;
+    
+    /* Destroy the layer/image */
+    CGLayerRelease(angbandLayer);
+    angbandLayer = NULL;
+
+    /* Font */
+    [angbandViewFont release];
+    angbandViewFont = nil;
+    
+    /* Window */
+    [primaryWindow setDelegate:nil];
+    [primaryWindow close];
+    [primaryWindow release];
+    primaryWindow = nil;
+    
+    /* Free overdraw cache (unless we're GC, in which case it was allocated collectable) */
+    if (! [NSGarbageCollector defaultCollector]) free(self->charOverdrawCache);
+    self->charOverdrawCache = NULL;
+    if (! [NSGarbageCollector defaultCollector]) free(self->attrOverdrawCache);
+    self->attrOverdrawCache = NULL;
+}
+
+/* Usual Cocoa fare */
+- (void)dealloc
+{
+    [self dispose];
+    [super dealloc];
+}
+
+
+
+#pragma mark -
+#pragma mark Directories and Paths Setup
+
+/**
+ *  Return the path for Angband's lib directory and bail if it isn't found. The lib directory should be in the bundle's resources directory, since it's copied when built.
+ */
++ (NSString *)libDirectoryPath
+{
+    NSString *bundleLibPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: AngbandDirectoryNameLib];
+    BOOL isDirectory = NO;
+    BOOL libExists = [[NSFileManager defaultManager] fileExistsAtPath: bundleLibPath isDirectory: &isDirectory];
+
+    if( !libExists || !isDirectory )
+    {
+        NSLog( @"[%@ %@]: can't find %@/ in bundle: isDirectory: %d libExists: %d", NSStringFromClass( [self class] ), NSStringFromSelector( _cmd ), AngbandDirectoryNameLib, isDirectory, libExists );
+        NSRunAlertPanel( @"Missing Resources", @"PosChengband was unable to find required resources and must quit. Please report a bug on the Angband forums.", @"Quit", nil, nil );
+        exit( 0 );
+    }
+
+    // angband requires the trailing slash for the directory path
+    return [bundleLibPath stringByAppendingString: @"/"];
+}
+
+/**
+ *  Return the path for the directory where Angband should look for its standard user file tree.
+ */
++ (NSString *)angbandDocumentsPath
+{
+    // angband requires the trailing slash, so we'll just add it here; NSString won't care about it when we use the base path for other things
+    NSString *documents = [NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES ) lastObject];
+
+#if defined(SAFE_DIRECTORY)
+    NSString *versionedDirectory = [NSString stringWithFormat: @"%@-%s", AngbandDirectoryNameBase, VERSION_STRING];
+    return [[documents stringByAppendingPathComponent: versionedDirectory] stringByAppendingString: @"/"];
+#else
+    return [[documents stringByAppendingPathComponent: AngbandDirectoryNameBase] stringByAppendingString: @"/"];
+#endif
+}
+
+/**
+ *  Give Angband the base paths that should be used for the various directories it needs. It will create any needed directories.
+ */
++ (void)prepareFilePathsAndDirectories
+{
+    char libpath[PATH_MAX + 1] = "\0";
+    char basepath[PATH_MAX + 1] = "\0";
+
+    [[self libDirectoryPath] getFileSystemRepresentation: libpath maxLength: sizeof(libpath)];
+    [[self angbandDocumentsPath] getFileSystemRepresentation: basepath maxLength: sizeof(basepath)];
+
+    init_file_paths( libpath, libpath, basepath );
+    create_needed_dirs();
+}
+
+#pragma mark -
+
+/* Entry point for initializing Angband */
++ (void)beginGame
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    
+    /* Hooks in some "z-util.c" hooks */
+    plog_aux = hook_plog;
+    quit_aux = hook_quit;
+    
+    // initialize file paths
+    [self prepareFilePathsAndDirectories];
+
+    // load preferences
+    load_prefs();
+    
+    // load sounds
+    load_sounds();
+    
+    /* Prepare the windows */
+    init_windows();
+    
+    /* Set up game event handlers */
+    //init_display();
+    
+       /* Register the sound hook */
+       //sound_hook = play_sound;
+    
+    /* Initialize */
+    init_angband();
+
+    /* Note the "system" */
+    ANGBAND_SYS = "mac";
+    
+    /* Initialize some save file stuff */
+    player_egid = getegid();
+    
+    /* Handle "open_when_ready" */
+    //handle_open_when_ready();
+    
+    /* Handle pending events (most notably update) and flush input */
+    Term_flush();
+    
+    /*
+     * Play a game -- "new_game" is set by "new", "open" or the open document
+     * even handler as appropriate
+     */
+        
+    [pool drain];
+    
+    /* Wait for response */
+    prt("[Choose 'New' or 'Open' from the 'File' menu]", 23, 17);
+    while (!game_in_progress) (check_events(CHECK_EVENTS_WAIT)); 
+
+    /* Play the game */
+    play_game(new_game);
+}
+
++ (void)endGame
+{    
+    /* Hack -- Forget messages */
+    msg_flag = FALSE;
+    
+    p_ptr->playing = FALSE;
+    p_ptr->leaving = TRUE;
+    quit_when_ready = TRUE;
+}
+
+
+- (IBAction)setGraphicsMode:(NSMenuItem *)sender
+{
+    /* We stashed the graphics mode ID in the menu item's tag */
+    graf_mode_req = [sender tag];
+
+    /* Stash it in UserDefaults */
+    [[NSUserDefaults angbandDefaults] setInteger:graf_mode_req forKey:@"GraphicsID"];
+    [[NSUserDefaults angbandDefaults] synchronize];
+    
+    if (game_in_progress)
+    {
+        /* Hack -- Force redraw */
+        do_cmd_redraw();
+        
+        /* Wake up the event loop so it notices the change */
+        wakeup_event_loop();
+    }
+}
+
+- (void)addAngbandView:(AngbandView *)view
+{
+    if (! [angbandViews containsObject:view])
+    {
+        [angbandViews addObject:view];
+        [self updateImage];
+        [self setNeedsDisplay:YES]; //we'll need to redisplay everything anyways, so avoid creating all those little redisplay rects
+        [self requestRedraw];
+    }
+}
+
+/* We have this notion of an "active" AngbandView, which is the largest - the idea being that in the screen saver, when the user hits Test in System Preferences, we don't want to keep driving the AngbandView in the background.  Our active AngbandView is the widest - that's a hack all right. Mercifully when we're just playing the game there's only one view. */
+- (AngbandView *)activeView
+{
+    if ([angbandViews count] == 1)
+        return [angbandViews objectAtIndex:0];
+    
+    AngbandView *result = nil;
+    float maxWidth = 0;
+    for (AngbandView *angbandView in angbandViews)
+    {
+        float width = [angbandView frame].size.width;
+        if (width > maxWidth)
+        {
+            maxWidth = width;
+            result = angbandView;
+        }
+    }
+    return result;
+}
+
+- (void)angbandViewDidScale:(AngbandView *)view
+{
+    /* If we're live-resizing with graphics, we're using the live resize optimization, so don't update the image. Otherwise do it. */
+    if (! (inLiveResize && graphics_are_enabled()) && view == [self activeView])
+    {
+        [self updateImage];
+        
+        [self setNeedsDisplay:YES]; //we'll need to redisplay everything anyways, so avoid creating all those little redisplay rects
+        [self requestRedraw];
+    }
+}
+
+
+- (void)removeAngbandView:(AngbandView *)view
+{
+    if ([angbandViews containsObject:view])
+    {
+        [angbandViews removeObject:view];
+        [self updateImage];
+        [self setNeedsDisplay:YES]; //we'll need to redisplay everything anyways, so avoid creating all those little redisplay rects
+        if ([angbandViews count]) [self requestRedraw];
+    }
+}
+
+
+static NSMenuItem *superitem(NSMenuItem *self)
+{
+    NSMenu *supermenu = [[self menu] supermenu];
+    int index = [supermenu indexOfItemWithSubmenu:[self menu]];
+    if (index == -1) return nil;
+    else return [supermenu itemAtIndex:index];
+}
+
+
+- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
+{
+    int tag = [menuItem tag];
+    SEL sel = [menuItem action];
+    if (sel == @selector(setGraphicsMode:))
+    {
+        [menuItem setState: (tag == graf_mode_req)];
+        return YES;
+    }
+    else
+    {
+        return YES;
+    }
+}
+
+- (NSWindow *)makePrimaryWindow
+{
+    if (! primaryWindow)
+    {
+        // this has to be done after the font is set, which it already is in term_init_cocoa()
+        CGFloat width = self->cols * tileSize.width + borderSize.width * 2.0;
+        CGFloat height = self->rows * tileSize.height + borderSize.height * 2.0;
+        NSRect contentRect = NSMakeRect( 0.0, 0.0, width, height );
+
+        NSUInteger styleMask = NSTitledWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask;
+
+        // make every window other than the main window closable
+        if( angband_term[0]->data != self )
+        {
+            styleMask |= NSClosableWindowMask;
+        }
+
+        primaryWindow = [[NSWindow alloc] initWithContentRect:contentRect styleMask: styleMask backing:NSBackingStoreBuffered defer:YES];
+
+        /* Not to be released when closed */
+        [primaryWindow setReleasedWhenClosed:NO];
+        [primaryWindow setExcludedFromWindowsMenu: YES]; // we're using custom window menu handling
+
+        /* Make the view */
+        AngbandView *angbandView = [[AngbandView alloc] initWithFrame:contentRect];
+        [angbandView setAngbandContext:self];
+        [angbandViews addObject:angbandView];
+        [primaryWindow setContentView:angbandView];
+        [angbandView release];
+
+        /* We are its delegate */
+        [primaryWindow setDelegate:self];
+
+        /* Update our image, since this is probably the first angband view we've gotten. */
+        [self updateImage];
+    }
+    return primaryWindow;
+}
+
+
+
+#pragma mark View/Window Passthrough
+
+/* This is what our views call to get us to draw to the window */
+- (void)drawRect:(NSRect)rect inView:(NSView *)view
+{
+    /* Take this opportunity to throttle so we don't flush faster than desird. */
+    BOOL viewInLiveResize = [view inLiveResize];
+    if (! viewInLiveResize) [self throttle];
+
+    /* With a GLayer, use CGContextDrawLayerInRect */
+    CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
+    NSRect bounds = [view bounds];
+    if (viewInLiveResize) CGContextSetInterpolationQuality(context, kCGInterpolationLow);
+    CGContextSetBlendMode(context, kCGBlendModeCopy);
+    CGContextDrawLayerInRect(context, *(CGRect *)&bounds, angbandLayer);
+    if (viewInLiveResize) CGContextSetInterpolationQuality(context, kCGInterpolationDefault);
+}
+
+
+- (void)orderFront
+{
+    [[[angbandViews lastObject] window] makeKeyAndOrderFront:self];
+}
+
+- (BOOL)isOrderedIn
+{
+    return [[[angbandViews lastObject] window] isVisible];
+}
+
+- (BOOL)isMainWindow
+{
+    return [[[angbandViews lastObject] window] isMainWindow];
+}
+
+- (void)orderOut
+{
+    [[[angbandViews lastObject] window] orderOut:self];
+}
+
+- (void)setNeedsDisplay:(BOOL)val
+{
+    for (NSView *angbandView in angbandViews)
+    {
+        [angbandView setNeedsDisplay:val];
+    }
+}
+
+- (void)setNeedsDisplayInBaseRect:(NSRect)rect
+{
+    for (NSView *angbandView in angbandViews)
+    {
+        [angbandView setNeedsDisplayInRect: rect];
+    }
+}
+
+- (void)displayIfNeeded
+{
+    [[self activeView] displayIfNeeded];
+}
+
+- (void)resizeOverdrawCache
+{
+    /* Free overdraw cache (unless we're GC, in which case it was allocated collectable) */
+    if (! [NSGarbageCollector defaultCollector]) free(self->charOverdrawCache);
+    self->charOverdrawCache = NULL;
+    if (! [NSGarbageCollector defaultCollector]) free(self->attrOverdrawCache);
+    self->attrOverdrawCache = NULL;
+
+    /* Allocate overdraw cache, unscanned and collectable. */
+    self->charOverdrawCache = NSAllocateCollectable(self->cols * self->rows *sizeof *charOverdrawCache, 0);
+    self->attrOverdrawCache = NSAllocateCollectable(self->cols * self->rows *sizeof *attrOverdrawCache, 0);
+}
+
+- (void)resizeTerminalWithContentRect: (NSRect)contentRect saveToDefaults: (BOOL)saveToDefaults
+{
+    CGFloat newRows = floor( (contentRect.size.height - (borderSize.height * 2.0)) / tileSize.height );
+    CGFloat newColumns = ceil( (contentRect.size.width - (borderSize.width * 2.0)) / tileSize.width );
+
+    self->cols = newColumns;
+    self->rows = newRows;
+    [self resizeOverdrawCache];
+
+    if( saveToDefaults )
+    {
+        int termIndex = 0;
+
+        for( termIndex = 0; termIndex < ANGBAND_TERM_MAX; termIndex++ )
+        {
+            if( angband_term[termIndex] == self->terminal )
+            {
+                break;
+            }
+        }
+
+        NSArray *terminals = [[NSUserDefaults standardUserDefaults] valueForKey: AngbandTerminalsDefaultsKey];
+
+        if( termIndex < (int)[terminals count] )
+        {
+            NSMutableDictionary *mutableTerm = [[NSMutableDictionary alloc] initWithDictionary: [terminals objectAtIndex: termIndex]];
+            [mutableTerm setValue: @(self->cols) forKey: AngbandTerminalColumnsDefaultsKey];
+            [mutableTerm setValue: @(self->rows) forKey: AngbandTerminalRowsDefaultsKey];
+
+            NSMutableArray *mutableTerminals = [[NSMutableArray alloc] initWithArray: terminals];
+            [mutableTerminals replaceObjectAtIndex: termIndex withObject: mutableTerm];
+
+            [[NSUserDefaults standardUserDefaults] setValue: mutableTerminals forKey: AngbandTerminalsDefaultsKey];
+            [mutableTerminals release];
+            [mutableTerm release];
+        }
+    }
+
+    term *old = Term;
+    Term_activate( self->terminal );
+    Term_resize( (int)newColumns, (int)newRows);
+    Term_redraw();
+    Term_activate( old );
+}
+
+#pragma mark -
+#pragma mark NSWindowDelegate Methods
+
+//- (void)windowWillStartLiveResize: (NSNotification *)notification
+//{
+//}
+
+- (void)windowDidEndLiveResize: (NSNotification *)notification
+{
+    NSWindow *window = [notification object];
+    NSRect contentRect = [window contentRectForFrameRect: [window frame]];
+    [self resizeTerminalWithContentRect: contentRect saveToDefaults: YES];
+}
+
+//- (NSSize)windowWillResize: (NSWindow *)sender toSize: (NSSize)frameSize
+//{
+//}
+
+- (void)windowDidEnterFullScreen: (NSNotification *)notification
+{
+    NSWindow *window = [notification object];
+    NSRect contentRect = [window contentRectForFrameRect: [window frame]];
+    [self resizeTerminalWithContentRect: contentRect saveToDefaults: NO];
+}
+
+- (void)windowDidExitFullScreen: (NSNotification *)notification
+{
+    NSWindow *window = [notification object];
+    NSRect contentRect = [window contentRectForFrameRect: [window frame]];
+    [self resizeTerminalWithContentRect: contentRect saveToDefaults: NO];
+}
+
+- (void)windowDidBecomeMain:(NSNotification *)notification
+{
+    NSWindow *window = [notification object];
+
+    if( window != self->primaryWindow )
+    {
+        return;
+    }
+
+    int termIndex = 0;
+
+    for( termIndex = 0; termIndex < ANGBAND_TERM_MAX; termIndex++ )
+    {
+        if( angband_term[termIndex] == self->terminal )
+        {
+            break;
+        }
+    }
+
+    NSMenuItem *item = [[[NSApplication sharedApplication] windowsMenu] itemWithTag: AngbandWindowMenuItemTagBase + termIndex];
+    [item setState: NSOnState];
+
+    if( [[NSFontPanel sharedFontPanel] isVisible] )
+    {
+        [[NSFontPanel sharedFontPanel] setPanelFont: [self selectionFont] isMultiple: NO];
+    }
+}
+
+- (void)windowDidResignMain: (NSNotification *)notification
+{
+    NSWindow *window = [notification object];
+
+    if( window != self->primaryWindow )
+    {
+        return;
+    }
+
+    int termIndex = 0;
+
+    for( termIndex = 0; termIndex < ANGBAND_TERM_MAX; termIndex++ )
+    {
+        if( angband_term[termIndex] == self->terminal )
+        {
+            break;
+        }
+    }
+
+    NSMenuItem *item = [[[NSApplication sharedApplication] windowsMenu] itemWithTag: AngbandWindowMenuItemTagBase + termIndex];
+    [item setState: NSOffState];
+}
+
+@end
+
+
+@implementation AngbandView
+
+- (BOOL)isOpaque
+{
+    return YES;
+}
+
+- (BOOL)isFlipped
+{
+    return YES;
+}
+
+- (void)drawRect:(NSRect)rect
+{
+    if (! angbandContext)
+    {
+        /* Draw bright orange, 'cause this ain't right */
+        [[NSColor orangeColor] set];
+        NSRectFill([self bounds]);
+    }
+    else
+    {
+        /* Tell the Angband context to draw into us */
+        [angbandContext drawRect:rect inView:self];
+    }
+}
+
+- (void)setAngbandContext:(AngbandContext *)context
+{
+    angbandContext = context;
+}
+
+- (AngbandContext *)angbandContext
+{
+    return angbandContext;
+}
+
+- (void)setFrameSize:(NSSize)size
+{
+    BOOL changed = ! NSEqualSizes(size, [self frame].size);
+    [super setFrameSize:size];
+    if (changed) [angbandContext angbandViewDidScale:self];
+}
+
+- (void)viewWillStartLiveResize
+{
+    [angbandContext viewWillStartLiveResize:self];
+}
+
+- (void)viewDidEndLiveResize
+{
+    [angbandContext viewDidEndLiveResize:self];
+}
+
+@end
+
+/*
+ * Delay handling of double-clicked savefiles
+ */
+Boolean open_when_ready = FALSE;
+
+
+
+/*** Some generic functions ***/
+
+/* Sets an Angband color at a given index */
+static void set_color_for_index(int idx)
+{
+    u16b rv, gv, bv;
+    
+    /* Extract the R,G,B data */
+    rv = angband_color_table[idx][1];
+    gv = angband_color_table[idx][2];
+    bv = angband_color_table[idx][3];
+    
+    CGContextSetRGBFillColor([[NSGraphicsContext currentContext] graphicsPort], rv/255., gv/255., bv/255., 1.);
+}
+
+/* Remember the current character in UserDefaults so we can select it by default next time. */
+static void record_current_savefile(void)
+{
+    NSString *savefileString = [[NSString stringWithCString:savefile encoding:NSMacOSRomanStringEncoding] lastPathComponent];
+    if (savefileString)
+    {
+        NSUserDefaults *angbandDefs = [NSUserDefaults angbandDefaults];
+        [angbandDefs setObject:savefileString forKey:@"SaveFile"];
+        [angbandDefs synchronize];        
+    }
+}
+
+
+/*** Support for the "z-term.c" package ***/
+
+
+/*
+ * Initialize a new Term
+ *
+ */
+static void Term_init_cocoa(term *t)
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    AngbandContext *context = [[AngbandContext alloc] init];
+    
+    /* Give the term a hard retain on context (for GC) */
+    t->data = (void *)CFRetain(context);
+    [context release];
+    
+    /* Handle graphics */
+    t->higher_pict = !! use_graphics;
+    t->always_pict = FALSE;
+    
+    NSDisableScreenUpdates();
+    
+    /* Figure out the frame autosave name based on the index of this term */
+    NSString *autosaveName = nil;
+    int termIdx;
+    for (termIdx = 0; termIdx < ANGBAND_TERM_MAX; termIdx++)
+    {
+        if (angband_term[termIdx] == t)
+        {
+            autosaveName = [NSString stringWithFormat:@"AngbandTerm-%d", termIdx];
+            break;
+        }
+    }
+    
+    /* Set its font. */
+    NSString *fontName = [[NSUserDefaults angbandDefaults] 
+        stringForKey:[NSString stringWithFormat:@"FontName-%d", termIdx]];
+    if (! fontName) fontName = [default_font fontName];
+    float fontSize = [[NSUserDefaults angbandDefaults] 
+        floatForKey:[NSString stringWithFormat:@"FontSize-%d", termIdx]];
+    if (! fontSize) fontSize = [default_font pointSize];
+    [context setSelectionFont:[NSFont fontWithName:fontName size:fontSize] adjustTerminal: NO];
+
+    NSArray *terminalDefaults = [[NSUserDefaults standardUserDefaults] valueForKey: AngbandTerminalsDefaultsKey];
+    NSInteger rows = 24;
+    NSInteger columns = 80;
+
+    if( termIdx < (int)[terminalDefaults count] )
+    {
+        NSDictionary *term = [terminalDefaults objectAtIndex: termIdx];
+        rows = [[term valueForKey: AngbandTerminalRowsDefaultsKey] integerValue];
+        columns = [[term valueForKey: AngbandTerminalColumnsDefaultsKey] integerValue];
+    }
+
+    context->cols = columns;
+    context->rows = rows;
+    [context resizeOverdrawCache];
+
+    /* Get the window */
+    NSWindow *window = [context makePrimaryWindow];
+    
+    /* Set its title and, for auxiliary terms, tentative size */
+    if (termIdx == 0)
+    {
+        [window setTitle:@"PosChengband"];
+    }
+    else
+    {
+        [window setTitle:[NSString stringWithFormat:@"Term %d", termIdx]];
+    }
+    
+    
+    /* If this is the first term, and we support full screen (Mac OS X Lion or later), then allow it to go full screen (sweet). Allow other terms to be FullScreenAuxilliary, so they can at least show up. Unfortunately in Lion they don't get brought to the full screen space; but they would only make sense on multiple displays anyways so it's not a big loss. */
+    if ([window respondsToSelector:@selector(toggleFullScreen:)])
+    {
+        NSWindowCollectionBehavior behavior = [window collectionBehavior];
+        behavior |= (termIdx == 0 ? Angband_NSWindowCollectionBehaviorFullScreenPrimary : Angband_NSWindowCollectionBehaviorFullScreenAuxiliary);
+        [window setCollectionBehavior:behavior];
+    }
+    
+    /* No Resume support yet, though it would not be hard to add */
+    if ([window respondsToSelector:@selector(setRestorable:)])
+    {
+        [window setRestorable:NO];
+    }
+    
+    /* Position the window, either through autosave or cascading it */
+    [window center];
+    
+    /* Cascade it */
+    static NSPoint lastPoint = {0, 0};
+    lastPoint = [window cascadeTopLeftFromPoint:lastPoint];
+    
+    /* And maybe that's all for naught */
+    if (autosaveName) [window setFrameAutosaveName:autosaveName];
+    
+    /* Tell it about its term. Do this after we've sized it so that the sizing doesn't trigger redrawing and such. */
+    [context setTerm:t];
+    
+    /* Only order front if it's the first term. Other terms will be ordered front from update_term_visibility(). This is to work around a problem where Angband aggressively tells us to initialize terms that don't do anything! */
+    if (t == angband_term[0]) [context orderFront];
+    
+    NSEnableScreenUpdates();
+    
+    /* Set "mapped" flag */
+    t->mapped_flag = true;
+    [pool drain];
+}
+
+
+
+/*
+ * Nuke an old Term
+ */
+static void Term_nuke_cocoa(term *t)
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    
+    AngbandContext *context = t->data;
+    if (context)
+    {
+        /* Tell the context to get rid of its windows, etc. */
+        [context dispose];
+        
+        /* Balance our CFRetain from when we created it */
+        CFRelease(context);
+        
+        /* Done with it */
+        t->data = NULL;
+    }
+    
+    [pool drain];
+}
+#if 0
+/* Returns the CGImageRef corresponding to an image with the given name in the resource directory, transferring ownership to the caller */
+static CGImageRef create_angband_image(NSString *name)
+{
+    CGImageRef decodedImage = NULL, result = NULL;
+    
+    /* Get the path to the image */
+    NSBundle *bundle = [NSBundle bundleForClass:[AngbandView class]];
+    NSString *path = [bundle pathForImageResource:name];
+    
+    /* Try using ImageIO to load it */
+    if (path)
+    {
+        NSURL *url = [[NSURL alloc] initFileURLWithPath:path isDirectory:NO];
+        if (url)
+        {
+            NSDictionary *options = [[NSDictionary alloc] initWithObjectsAndKeys:(id)kCFBooleanTrue, kCGImageSourceShouldCache, nil];
+            CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)url, (CFDictionaryRef)options);
+            if (source)
+            {
+                /* We really want the largest image, but in practice there's only going to be one */
+                decodedImage = CGImageSourceCreateImageAtIndex(source, 0, (CFDictionaryRef)options);
+                CFRelease(source);
+            }
+            [options release];
+            [url release];
+        }
+    }
+    
+    /* Draw the sucker to defeat ImageIO's weird desire to cache and decode on demand. Our images aren't that big! */
+    if (decodedImage)
+    {
+        size_t width = CGImageGetWidth(decodedImage), height = CGImageGetHeight(decodedImage);
+        
+        /* Compute our own bitmap info */
+        CGBitmapInfo imageBitmapInfo = CGImageGetBitmapInfo(decodedImage);
+        CGBitmapInfo contextBitmapInfo = kCGBitmapByteOrderDefault;
+        
+        switch (imageBitmapInfo & kCGBitmapAlphaInfoMask) {
+            case kCGImageAlphaNone:
+            case kCGImageAlphaNoneSkipLast:
+            case kCGImageAlphaNoneSkipFirst:
+                /* No alpha */
+                contextBitmapInfo |= kCGImageAlphaNone;
+                break;
+            default:
+                /* Some alpha, use premultiplied last which is most efficient. */
+                contextBitmapInfo |= kCGImageAlphaPremultipliedLast;
+                break;
+        }
+        
+        CGContextRef ctx = CGBitmapContextCreate(NULL, width, height, CGImageGetBitsPerComponent(decodedImage), CGImageGetBytesPerRow(decodedImage), CGImageGetColorSpace(decodedImage), contextBitmapInfo);
+        CGContextSetBlendMode(ctx, kCGBlendModeCopy);
+        CGContextDrawImage(ctx, CGRectMake(0, 0, width, height), decodedImage);
+        result = CGBitmapContextCreateImage(ctx);
+        
+        /* Done with these things */
+        CFRelease(ctx);
+        CGImageRelease(decodedImage);
+    }
+    return result;
+}
+#endif
+/*
+ * React to changes
+ */
+static errr Term_xtra_cocoa_react(void)
+{
+    /* Don't actually switch graphics until the game is running */
+    if (!initialized || !game_in_progress) return (-1);
+
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    //AngbandContext *angbandContext = Term->data;
+#if 0    
+    /* Handle graphics */
+    int expected_graf_mode = (current_graphics_mode ? current_graphics_mode->grafID : GRAF_MODE_NONE);
+    if (graf_mode_req != expected_graf_mode)
+    {
+        graphics_mode *new_mode;
+               if (graf_mode_req != GRAF_MODE_NONE) {
+                       new_mode = get_graphics_mode(graf_mode_req);
+               } else {
+                       new_mode = NULL;
+        }
+        
+        /* Get rid of the old image. CGImageRelease is NULL-safe. */
+        CGImageRelease(pict_image);
+        pict_image = NULL;
+        
+        /* Try creating the image if we want one */
+        if (new_mode != NULL)
+        {
+            NSString *img_name = [NSString stringWithCString:new_mode->file 
+                                                encoding:NSMacOSRomanStringEncoding];
+            pict_image = create_angband_image(img_name);
+
+            /* If we failed to create the image, set the new desired mode to NULL */
+            if (! pict_image)
+                new_mode = NULL;
+        }
+        
+        /* Record what we did */
+        use_graphics = (new_mode != NULL);
+        use_transparency = (new_mode != NULL);
+        ANGBAND_GRAF = (new_mode ? new_mode->pref : NULL);
+        current_graphics_mode = new_mode;
+        
+        /* Enable or disable higher picts. Note: this should be done for all terms. */
+        angbandContext->terminal->higher_pict = !! use_graphics;
+        
+        if (pict_image && current_graphics_mode)
+        {
+            /* Compute the row and column count via the image height and width. */
+            pict_rows = (int)(CGImageGetHeight(pict_image) / current_graphics_mode->cell_height);
+            pict_cols = (int)(CGImageGetWidth(pict_image) / current_graphics_mode->cell_width);
+        }
+        else
+        {
+            pict_rows = 0;
+            pict_cols = 0;
+        }
+        
+        /* Reset visuals */
+        if (initialized && game_in_progress)
+        {
+            reset_visuals(TRUE);
+        }
+    }
+#endif    
+    [pool drain];
+    
+    /* Success */
+    return (0);
+}
+
+
+/*
+ * Do a "special thing"
+ */
+static errr Term_xtra_cocoa(int n, int v)
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    AngbandContext* angbandContext = Term->data;
+    
+    errr result = 0;
+    
+    /* Analyze */
+    switch (n)
+    {
+            /* Make a noise */
+        case TERM_XTRA_NOISE:
+        {
+            /* Make a noise */
+            NSBeep();
+            
+            /* Success */
+            break;
+        }
+            
+            /* Process random events */
+        case TERM_XTRA_BORED:
+        {
+            // show or hide cocoa windows based on the subwindow flags set by the user
+            AngbandUpdateWindowVisibility();
+
+            /* Process an event */
+            (void)check_events(CHECK_EVENTS_NO_WAIT);
+            
+            /* Success */
+            break;
+        }
+            
+            /* Process pending events */
+        case TERM_XTRA_EVENT:
+        {
+            /* Process an event */
+            (void)check_events(v);
+            
+            /* Success */
+            break;
+        }
+            
+            /* Flush all pending events (if any) */
+        case TERM_XTRA_FLUSH:
+        {
+            /* Hack -- flush all events */
+            while (check_events(CHECK_EVENTS_DRAIN)) /* loop */;
+            
+            /* Success */
+            break;
+        }
+            
+            /* Hack -- Change the "soft level" */
+        case TERM_XTRA_LEVEL:
+        {
+            /* Here we could activate (if requested), but I don't think Angband should be telling us our window order (the user should decide that), so do nothing. */            
+            break;
+        }
+            
+            /* Clear the screen */
+        case TERM_XTRA_CLEAR:
+        {        
+            [angbandContext lockFocus];
+            [[NSColor blackColor] set];
+            NSRect imageRect = {NSZeroPoint, [angbandContext imageSize]};            
+            NSRectFillUsingOperation(imageRect, NSCompositeCopy);
+            [angbandContext unlockFocus];
+            [angbandContext clearOverdrawCache];
+            [angbandContext setNeedsDisplay:YES];
+            /* Success */
+            break;
+        }
+            
+            /* React to changes */
+        case TERM_XTRA_REACT:
+        {
+            /* React to changes */
+            return (Term_xtra_cocoa_react());
+        }
+            
+            /* Delay (milliseconds) */
+        case TERM_XTRA_DELAY:
+        {
+            /* If needed */
+            if (v > 0)
+            {
+                
+                double seconds = v / 1000.;
+                NSDate* date = [NSDate dateWithTimeIntervalSinceNow:seconds];
+                do
+                {
+                    NSEvent* event;
+                    do
+                    {
+                        event = [NSApp nextEventMatchingMask:-1 untilDate:date inMode:NSDefaultRunLoopMode dequeue:YES];
+                        if (event) send_event(event);
+                    } while (event);
+                } while ([date timeIntervalSinceNow] >= 0);
+                
+            }
+            
+            /* Success */
+            break;
+        }
+            
+        case TERM_XTRA_FRESH:
+        {
+            /* No-op -- see #1669 
+             * [angbandContext displayIfNeeded]; */
+            break;
+        }
+            
+        default:
+            /* Oops */
+            result = 1;
+            break;
+    }
+    
+    [pool drain];
+    
+    /* Oops */
+    return result;
+}
+
+static errr Term_curs_cocoa(int x, int y)
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    AngbandContext *angbandContext = Term->data;
+    
+    /* Get the tile */
+    NSRect rect = [angbandContext rectInImageForTileAtX:x Y:y];
+    
+    /* We'll need to redisplay in that rect */
+    NSRect redisplayRect = rect;
+
+    /* Go to the pixel boundaries corresponding to this tile */
+    rect = crack_rect(rect, AngbandScaleIdentity, push_options(x, y));
+    
+    /* Lock focus and draw it */
+    [angbandContext lockFocus];
+    [[NSColor yellowColor] set];
+    NSFrameRectWithWidth(rect, 1);
+    [angbandContext unlockFocus];
+    
+    /* Invalidate that rect */
+    [angbandContext setNeedsDisplayInBaseRect:redisplayRect];
+    
+    /* Success */
+    [pool drain];
+    return 0;
+}
+
+/*
+ * Low level graphics (Assumes valid input)
+ *
+ * Erase "n" characters starting at (x,y)
+ */
+static errr Term_wipe_cocoa(int x, int y, int n)
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    AngbandContext *angbandContext = Term->data;
+    
+    /* clear our overdraw cache for subpixel rendering */
+    [angbandContext clearOverdrawCache];
+    
+    /* Erase the block of characters */
+    NSRect rect = [angbandContext rectInImageForTileAtX:x Y:y];
+    
+    /* Maybe there's more than one */
+    if (n > 1) rect = NSUnionRect(rect, [angbandContext rectInImageForTileAtX:x + n-1 Y:y]);
+    
+    /* Lock focus and clear */
+    [angbandContext lockFocus];
+    [[NSColor blackColor] set];
+    NSRectFill(rect);
+    [angbandContext unlockFocus];    
+    [angbandContext setNeedsDisplayInBaseRect:rect];
+    
+    [pool drain];
+    
+    /* Success */
+    return (0);
+}
+#if 0
+static void draw_image_tile(CGImageRef image, NSRect srcRect, NSRect dstRect, NSCompositingOperation op)
+{
+    /* When we use high-quality resampling to draw a tile, pixels from outside the tile may bleed in, causing graphics artifacts. Work around that. */
+    CGImageRef subimage = CGImageCreateWithImageInRect(image, *(CGRect *)&srcRect);
+    NSGraphicsContext *context = [NSGraphicsContext currentContext];
+    [context setCompositingOperation:op];
+    CGContextDrawImage([context graphicsPort], *(CGRect *)&dstRect, subimage);
+    CGImageRelease(subimage);
+}
+
+static errr Term_pict_cocoa(int x, int y, int n, const int *ap,
+                            const wchar_t *cp, const int *tap,
+                            const wchar_t *tcp)
+{
+    
+    /* Paranoia: Bail if we don't have a current graphics mode */
+    if (! current_graphics_mode) return -1;
+    
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    AngbandContext* angbandContext = Term->data;
+
+    /* Indicate that we have a picture here (and hence this should not be overdrawn by Term_text_cocoa) */
+    angbandContext->charOverdrawCache[y * angbandContext->cols + x] = NO_OVERDRAW;
+    
+    /* Lock focus */
+    [angbandContext lockFocus];
+    
+    NSRect destinationRect = [angbandContext rectInImageForTileAtX:x Y:y];
+
+    /* Expand the rect to every touching pixel to figure out what to redisplay */
+    NSRect redisplayRect = crack_rect(destinationRect, AngbandScaleIdentity, PUSH_RIGHT | PUSH_TOP | PUSH_BOTTOM | PUSH_LEFT);
+    
+    /* Expand our destinationRect */
+    destinationRect = crack_rect(destinationRect, AngbandScaleIdentity, push_options(x, y));
+    
+    /* Scan the input */
+    int i;
+    int graf_width = current_graphics_mode->cell_width;
+    int graf_height = current_graphics_mode->cell_height;
+
+    for (i = 0; i < n; i++)
+    {
+        
+        int a = *ap++;
+        wchar_t c = *cp++;
+        
+        int ta = *tap++;
+        wchar_t tc = *tcp++;
+        
+        
+        /* Graphics -- if Available and Needed */
+        if (use_graphics && (a & 0x80) && (c & 0x80))
+        {
+            int col, row;
+            int t_col, t_row;
+            
+
+            /* Primary Row and Col */
+            row = ((byte)a & 0x7F) % pict_rows;
+            col = ((byte)c & 0x7F) % pict_cols;
+            
+            NSRect sourceRect;
+            sourceRect.origin.x = col * graf_width;
+            sourceRect.origin.y = row * graf_height;
+            sourceRect.size.width = graf_width;
+            sourceRect.size.height = graf_height;
+            
+            /* Terrain Row and Col */
+            t_row = ((byte)ta & 0x7F) % pict_rows;
+            t_col = ((byte)tc & 0x7F) % pict_cols;
+            
+            NSRect terrainRect;
+            terrainRect.origin.x = t_col * graf_width;
+            terrainRect.origin.y = t_row * graf_height;
+            terrainRect.size.width = graf_width;
+            terrainRect.size.height = graf_height;
+            
+            /* Transparency effect. We really want to check current_graphics_mode->alphablend, but as of this writing that's never set, so we do something lame.  */
+            //if (current_graphics_mode->alphablend)
+            if (graf_width > 8 || graf_height > 8)
+            {
+                draw_image_tile(pict_image, terrainRect, destinationRect, NSCompositeCopy);
+                draw_image_tile(pict_image, sourceRect, destinationRect, NSCompositeSourceOver); 
+            }
+            else
+            {
+                draw_image_tile(pict_image, sourceRect, destinationRect, NSCompositeCopy);
+            }
+        }        
+    }
+    
+    [angbandContext unlockFocus];
+    [angbandContext setNeedsDisplayInBaseRect:redisplayRect];
+    
+    [pool drain];
+    
+    /* Success */
+    return (0);
+}
+#endif
+/*
+ * Low level graphics.  Assumes valid input.
+ *
+ * Draw several ("n") chars, with an attr, at a given location.
+ */
+static errr Term_text_cocoa(int x, int y, int n, byte_hack a, cptr cp)
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+    /* Subpixel rendering looks really nice!  Unfortunately, drawing a string like this:
+     .@
+     causes subpixels to extend slightly into the region 'owned' by the period.  This means that when the user presses right,
+     those subpixels 'owned' by the period above do not get redrawn by Angband, so we leave little blue and red subpixel turds
+     all over the screen.  Turning off subpixel rendering fixes this, as does increasing the font advance by a pixel, but that is
+     ugly.  Our hack solution is to remember all of the characters we draw as well as their locations and colors (in charOverdrawCache),
+     and then re-blit the previous and next character (if any).
+     */
+    
+    NSRect redisplayRect = NSZeroRect;
+    AngbandContext* angbandContext = Term->data;
+    
+    /* record our data in our cache */
+    int start = y * angbandContext->cols + x;
+    int location;
+    for (location = 0; location < n; location++) {
+        angbandContext->charOverdrawCache[start + location] = cp[location];
+        angbandContext->attrOverdrawCache[start + location] = a;
+    }
+    
+    /* Focus on our layer */
+    [angbandContext lockFocus];
+
+    /* Starting pixel */
+    NSRect charRect = [angbandContext rectInImageForTileAtX:x Y:y];
+    
+    const CGFloat tileWidth = angbandContext->tileSize.width;
+    
+    /* erase behind us */
+    unsigned leftPushOptions = push_options(x, y);
+    unsigned rightPushOptions = push_options(x + n - 1, y);
+    leftPushOptions &= ~ PUSH_RIGHT;
+    rightPushOptions &= ~ PUSH_LEFT;
+#if 0    
+    switch (a / MAX_COLORS) {
+    case BG_BLACK:
+           [[NSColor blackColor] set];
+           break;
+    case BG_SAME:
+           set_color_for_index(a % MAX_COLORS);
+           break;
+    case BG_DARK:
+           set_color_for_index(TERM_SHADE);
+           break;
+    }
+#endif    
+    NSRect rectToClear = charRect;
+    rectToClear.size.width = tileWidth * n;
+    NSRectFill(crack_rect(rectToClear, AngbandScaleIdentity, leftPushOptions | rightPushOptions));
+    
+    NSFont *selectionFont = [[angbandContext selectionFont] screenFont];
+    [selectionFont set];
+    
+    /* Handle overdraws */
+    const int overdraws[2] = {x-1, x+n}; //left, right
+    int i;
+    for (i=0; i < 2; i++) {
+        int overdrawX = overdraws[i];
+        
+        // Nothing to overdraw if we're at an edge
+        if (overdrawX >= 0 && (size_t)overdrawX < angbandContext->cols)
+        {
+            wchar_t previouslyDrawnVal = angbandContext->charOverdrawCache[y * angbandContext->cols + overdrawX];
+           //int previouslyDrawnAttr = angbandContext->attrOverdrawCache[y * angbandContext->cols + overdrawX];
+            // Don't overdraw if it's not text
+            if (previouslyDrawnVal != NO_OVERDRAW)
+            {
+                NSRect overdrawRect = [angbandContext rectInImageForTileAtX:overdrawX Y:y];
+                NSRect expandedRect = crack_rect(overdrawRect, AngbandScaleIdentity, push_options(overdrawX, y));
+#if 0                
+                // Make sure we redisplay it
+               switch (previouslyDrawnAttr / MAX_COLORS) {
+               case BG_BLACK:
+                   [[NSColor blackColor] set];
+                   break;
+               case BG_SAME:
+                   set_color_for_index(previouslyDrawnAttr % MAX_COLORS);
+                   break;
+               case BG_DARK:
+                   set_color_for_index(TERM_SHADE);
+                   break;
+               }
+#endif
+                NSRectFill(expandedRect);
+                redisplayRect = NSUnionRect(redisplayRect, expandedRect);
+                
+                // Redraw text if we have any
+                if (previouslyDrawnVal != 0)
+                {
+                    byte color = angbandContext->attrOverdrawCache[y * angbandContext->cols + overdrawX]; 
+                    
+                    set_color_for_index(color);
+                    [angbandContext drawWChar:previouslyDrawnVal inRect:overdrawRect];
+                }
+            }
+        }
+    }
+    
+    /* Set the color */
+    set_color_for_index(a % MAX_COLORS);
+    
+    /* Draw each */
+    NSRect rectToDraw = charRect;
+    for (i=0; i < n; i++) {
+        [angbandContext drawWChar:cp[i] inRect:rectToDraw];
+        rectToDraw.origin.x += tileWidth;
+    }
+
+    
+    // Invalidate what we just drew
+    NSRect drawnRect = charRect;
+    drawnRect.size.width = tileWidth * n;
+    redisplayRect = NSUnionRect(redisplayRect, drawnRect);
+    
+    [angbandContext unlockFocus];    
+    [angbandContext setNeedsDisplayInBaseRect:redisplayRect];
+    
+    [pool drain];
+    
+    /* Success */
+    return (0);
+}
+#if 0
+/* From the Linux mbstowcs(3) man page:
+ *   If dest is NULL, n is ignored, and the conversion  proceeds  as  above,
+ *   except  that  the converted wide characters are not written out to mem‐
+ *   ory, and that no length limit exists.
+ */
+static size_t Term_mbcs_cocoa(wchar_t *dest, const char *src, int n)
+{
+    int i;
+    int count = 0;
+
+    /* Unicode code point to UTF-8
+     *  0x0000-0x007f:   0xxxxxxx
+     *  0x0080-0x07ff:   110xxxxx 10xxxxxx
+     *  0x0800-0xffff:   1110xxxx 10xxxxxx 10xxxxxx
+     * 0x10000-0x1fffff: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+     * Note that UTF-16 limits Unicode to 0x10ffff. This code is not
+     * endian-agnostic.
+     */
+    for (i = 0; i < n || dest == NULL; i++) {
+        if ((src[i] & 0x80) == 0) {
+            if (dest != NULL) dest[count] = src[i];
+            if (src[i] == 0) break;
+        } else if ((src[i] & 0xe0) == 0xc0) {
+            if (dest != NULL) dest[count] = 
+                            (((unsigned char)src[i] & 0x1f) << 6)| 
+                            ((unsigned char)src[i+1] & 0x3f);
+            i++;
+        } else if ((src[i] & 0xf0) == 0xe0) {
+            if (dest != NULL) dest[count] = 
+                            (((unsigned char)src[i] & 0x0f) << 12) | 
+                            (((unsigned char)src[i+1] & 0x3f) << 6) |
+                            ((unsigned char)src[i+2] & 0x3f);
+            i += 2;
+        } else if ((src[i] & 0xf8) == 0xf0) {
+            if (dest != NULL) dest[count] = 
+                            (((unsigned char)src[i] & 0x0f) << 18) | 
+                            (((unsigned char)src[i+1] & 0x3f) << 12) |
+                            (((unsigned char)src[i+2] & 0x3f) << 6) |
+                            ((unsigned char)src[i+3] & 0x3f);
+            i += 3;
+        } else {
+            /* Found an invalid multibyte sequence */
+            return (size_t)-1;
+        }
+        count++;
+    }
+    return count;
+}
+#endif
+/* Post a nonsense event so that our event loop wakes up */
+static void wakeup_event_loop(void)
+{
+    /* Big hack - send a nonsense event to make us update */
+    NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint modifierFlags:0 timestamp:0 windowNumber:0 context:NULL subtype:AngbandEventWakeup data1:0 data2:0];
+    [NSApp postEvent:event atStart:NO];
+}
+
+
+/*
+ * Create and initialize window number "i"
+ */
+static term *term_data_link(int i)
+{
+    NSArray *terminalDefaults = [[NSUserDefaults standardUserDefaults] valueForKey: AngbandTerminalsDefaultsKey];
+    NSInteger rows = 24;
+    NSInteger columns = 80;
+
+    if( i < (int)[terminalDefaults count] )
+    {
+        NSDictionary *term = [terminalDefaults objectAtIndex: i];
+        rows = [[term valueForKey: AngbandTerminalRowsDefaultsKey] integerValue];
+        columns = [[term valueForKey: AngbandTerminalColumnsDefaultsKey] integerValue];
+    }
+
+    /* Allocate */
+    term *newterm = ZNEW(term);
+
+    /* Initialize the term */
+    term_init(newterm, columns, rows, 256 /* keypresses, for some reason? */);
+    
+    /* Differentiate between BS/^h, Tab/^i, etc. */
+    //newterm->complex_input = TRUE;
+
+    /* Use a "software" cursor */
+    newterm->soft_cursor = TRUE;
+    
+    /* Erase with "white space" */
+    newterm->attr_blank = TERM_WHITE;
+    newterm->char_blank = ' ';
+    
+    /* Prepare the init/nuke hooks */
+    newterm->init_hook = Term_init_cocoa;
+    newterm->nuke_hook = Term_nuke_cocoa;
+    
+    /* Prepare the function hooks */
+    newterm->xtra_hook = Term_xtra_cocoa;
+    newterm->wipe_hook = Term_wipe_cocoa;
+    newterm->curs_hook = Term_curs_cocoa;
+    newterm->text_hook = Term_text_cocoa;
+    //newterm->pict_hook = Term_pict_cocoa;
+    //newterm->mbcs_hook = Term_mbcs_cocoa;
+    
+    /* Global pointer */
+    angband_term[i] = newterm;
+    
+    return newterm;
+}
+
+/*
+ * Load preferences from preferences file for current host+current user+
+ * current application.
+ */
+static void load_prefs()
+{
+    NSUserDefaults *defs = [NSUserDefaults angbandDefaults];
+    
+    /* Make some default defaults */
+    NSMutableArray *defaultTerms = [[NSMutableArray alloc] init];
+    NSDictionary *standardTerm = @{
+                                   AngbandTerminalRowsDefaultsKey : @24,
+                                   AngbandTerminalColumnsDefaultsKey : @80,
+                                   };
+    
+    for( NSUInteger i = 0; i < 9; i++ )
+    {
+        [defaultTerms addObject: standardTerm];
+    }
+
+    NSDictionary *defaults = [[NSDictionary alloc] initWithObjectsAndKeys:
+                              @"Menlo", @"FontName",
+                              [NSNumber numberWithFloat:13.f], @"FontSize",
+                              [NSNumber numberWithInt:60], @"FramesPerSecond",
+                              [NSNumber numberWithBool:YES], @"AllowSound",
+                              [NSNumber numberWithInt:GRAPHICS_NONE], @"GraphicsID",
+                              defaultTerms, AngbandTerminalsDefaultsKey,
+                              nil];
+    [defs registerDefaults:defaults];
+    [defaults release];
+    [defaultTerms release];
+    
+    /* preferred graphics mode */
+    graf_mode_req = [defs integerForKey:@"GraphicsID"];
+    
+    /* use sounds */
+    allow_sounds = [defs boolForKey:@"AllowSound"];
+    
+    /* fps */
+    frames_per_second = [[NSUserDefaults angbandDefaults] integerForKey:@"FramesPerSecond"];
+    
+    /* font */
+    default_font = [[NSFont fontWithName:[defs valueForKey:@"FontName-0"] size:[defs floatForKey:@"FontSize-0"]] retain];
+    if (! default_font) default_font = [[NSFont fontWithName:@"Menlo" size:13.] retain];
+}
+
+/* Arbitary limit on number of possible samples per event */
+#define MAX_SAMPLES            8
+
+/* Struct representing all data for a set of event samples */
+typedef struct
+{
+       int num;        /* Number of available samples for this event */
+       NSSound *sound[MAX_SAMPLES];
+} sound_sample_list;
+
+/* Array of event sound structs */
+//static sound_sample_list samples[MSG_MAX];
+
+
+/*
+ * Load sound effects based on sound.cfg within the xtra/sound directory;
+ * bridge to Cocoa to use NSSound for simple loading and playback, avoiding
+ * I/O latency by cacheing all sounds at the start.  Inherits full sound
+ * format support from Quicktime base/plugins.
+ * pelpel favoured a plist-based parser for the future but .cfg support
+ * improves cross-platform compatibility.
+ */
+static void load_sounds(void)
+{
+#if 0
+       char path[2048];
+       char buffer[2048];
+       ang_file *fff;
+    
+       /* Build the "sound" path */
+       path_build(path, sizeof(path), ANGBAND_DIR_XTRA, "sound");
+       ANGBAND_DIR_XTRA_SOUND = string_make(path);
+    
+       /* Find and open the config file */
+       path_build(path, sizeof(path), ANGBAND_DIR_XTRA_SOUND, "sound.cfg");
+       fff = file_open(path, MODE_READ, -1);
+    
+       /* Handle errors */
+       if (!fff)
+       {
+               NSLog(@"The sound configuration file could not be opened.");
+               return;
+       }
+       
+       /* Instantiate an autorelease pool for use by NSSound */
+       NSAutoreleasePool *autorelease_pool;
+       autorelease_pool = [[NSAutoreleasePool alloc] init];
+    
+    /* Use a dictionary to unique sounds, so we can share NSSounds across multiple events */
+    NSMutableDictionary *sound_dict = [NSMutableDictionary dictionary];
+    
+       /*
+        * This loop may take a while depending on the count and size of samples
+        * to load.
+        */
+    
+       /* Parse the file */
+       /* Lines are always of the form "name = sample [sample ...]" */
+       while (file_getl(fff, buffer, sizeof(buffer)))
+       {
+               char *msg_name;
+               char *cfg_sample_list;
+               char *search;
+               char *cur_token;
+               char *next_token;
+               int event;
+        
+               /* Skip anything not beginning with an alphabetic character */
+               if (!buffer[0] || !isalpha((unsigned char)buffer[0])) continue;
+        
+               /* Split the line into two: message name, and the rest */
+               search = strchr(buffer, ' ');
+               cfg_sample_list = strchr(search + 1, ' ');
+               if (!search) continue;
+               if (!cfg_sample_list) continue;
+        
+               /* Set the message name, and terminate at first space */
+               msg_name = buffer;
+               search[0] = '\0';
+        
+               /* Make sure this is a valid event name */
+               for (event = MSG_MAX - 1; event >= 0; event--)
+               {
+                       if (strcmp(msg_name, angband_sound_name[event]) == 0)
+                               break;
+               }
+               if (event < 0) continue;
+        
+               /* Advance the sample list pointer so it's at the beginning of text */
+               cfg_sample_list++;
+               if (!cfg_sample_list[0]) continue;
+        
+               /* Terminate the current token */
+               cur_token = cfg_sample_list;
+               search = strchr(cur_token, ' ');
+               if (search)
+               {
+                       search[0] = '\0';
+                       next_token = search + 1;
+               }
+               else
+               {
+                       next_token = NULL;
+               }
+        
+               /*
+                * Now we find all the sample names and add them one by one
+                */
+               while (cur_token)
+               {
+                       int num = samples[event].num;
+            
+                       /* Don't allow too many samples */
+                       if (num >= MAX_SAMPLES) break;
+            
+            NSString *token_string = [NSString stringWithUTF8String:cur_token];
+            NSSound *sound = [sound_dict objectForKey:token_string];
+            
+            if (! sound)
+            {
+                /* We have to load the sound. Build the path to the sample */
+                path_build(path, sizeof(path), ANGBAND_DIR_XTRA_SOUND, cur_token);
+                if (file_exists(path))
+                {
+                    
+                    /* Load the sound into memory */
+                    sound = [[[NSSound alloc] initWithContentsOfFile:[NSString stringWithUTF8String:path] byReference:YES] autorelease];
+                    if (sound) [sound_dict setObject:sound forKey:token_string];
+                }
+            }
+            
+            /* Store it if we loaded it */
+            if (sound)
+            {
+                samples[event].sound[num] = [sound retain];
+                
+                /* Imcrement the sample count */
+                samples[event].num++;
+            }
+            
+            
+                       /* Figure out next token */
+                       cur_token = next_token;
+                       if (next_token)
+                       {
+                               /* Try to find a space */
+                               search = strchr(cur_token, ' ');
+                
+                               /* If we can find one, terminate, and set new "next" */
+                               if (search)
+                               {
+                                       search[0] = '\0';
+                                       next_token = search + 1;
+                               }
+                               else
+                               {
+                                       /* Otherwise prevent infinite looping */
+                                       next_token = NULL;
+                               }
+                       }
+               }
+       }
+    
+       /* Release the autorelease pool */
+       [autorelease_pool release];
+    
+       /* Close the file */
+       file_close(fff);
+#endif
+}
+#if 0
+/*
+ * Play sound effects asynchronously.  Select a sound from any available
+ * for the required event, and bridge to Cocoa to play it.
+ */
+static void play_sound(int event)
+{    
+    /* Maybe block it */
+    if (! allow_sounds) return;
+    
+       /* Paranoia */
+       if (event < 0 || event >= MSG_MAX) return;
+    
+    /* Load sounds just-in-time (once) */
+    static BOOL loaded = NO;
+    if (! loaded)
+    {
+        loaded = YES;
+        load_sounds();
+    }
+    
+    /* Check there are samples for this event */
+    if (!samples[event].num) return;
+    
+    /* Instantiate an autorelease pool for use by NSSound */
+    NSAutoreleasePool *autorelease_pool;
+    autorelease_pool = [[NSAutoreleasePool alloc] init];
+    
+    /* Choose a random event */
+    int s = randint0(samples[event].num);
+    
+    /* Stop the sound if it's currently playing */
+    if ([samples[event].sound[s] isPlaying])
+        [samples[event].sound[s] stop];
+    
+    /* Play the sound */
+    [samples[event].sound[s] play];
+    
+    /* Release the autorelease pool */
+    [autorelease_pool drain];
+}
+#endif
+/*
+ * 
+ */
+static void init_windows(void)
+{
+    /* Create the main window */
+    term *primary = term_data_link(0);
+    
+    /* Prepare to create any additional windows */
+    int i;
+    for (i=1; i < ANGBAND_TERM_MAX; i++) {
+        term_data_link(i);
+    }
+    
+    /* Activate the primary term */
+    Term_activate(primary);
+}
+
+#if 0
+/*
+ *    Run the event loop and return a gameplay status to init_angband
+ */
+static errr get_cmd_init(void)
+{     
+    if (cmd.command == CMD_NULL)
+    {
+        /* Prompt the user */ 
+        prt("[Choose 'New' or 'Open' from the 'File' menu]", 23, 17);
+        Term_fresh();
+        
+        while (cmd.command == CMD_NULL) {
+            NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+            NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantFuture] inMode:NSDefaultRunLoopMode dequeue:YES];
+            if (event) [NSApp sendEvent:event];
+            [pool drain];        
+        }
+    }
+    
+    /* Push the command to the game. */
+    cmd_insert_s(&cmd);
+    
+    return 0; 
+} 
+
+
+/* Return a command */
+static errr cocoa_get_cmd(cmd_context context, bool wait)
+{
+    if (context == CMD_INIT) 
+        return get_cmd_init();
+    else 
+        return textui_get_cmd(context, wait);
+}
+#endif
+/* Return the directory into which we put data (save and config) */
+static NSString *get_data_directory(void)
+{
+    return [@"~/Documents/PosChengband/" stringByExpandingTildeInPath];
+}
+
+/*
+ * Handle the "open_when_ready" flag
+ */
+static void handle_open_when_ready(void)
+{
+    /* Check the flag XXX XXX XXX make a function for this */
+    if (open_when_ready && initialized && !game_in_progress)
+    {
+        /* Forget */
+        open_when_ready = FALSE;
+        
+        /* Game is in progress */
+        game_in_progress = TRUE;
+        
+        /* Wait for a keypress */
+        pause_line(23);
+    }
+}
+
+
+/*
+ * Handle quit_when_ready, by Peter Ammon,
+ * slightly modified to check inkey_flag.
+ */
+static void quit_calmly(void)
+{
+    /* Quit immediately if game's not started */
+    if (!game_in_progress || !character_generated) quit(NULL);
+    
+    /* Save the game and Quit (if it's safe) */
+    if (inkey_flag)
+    {
+        /* Hack -- Forget messages */
+        msg_flag = FALSE;
+        
+        /* Save the game */
+        do_cmd_save_game(FALSE);
+        record_current_savefile();
+        
+        
+        /* Quit */
+        quit(NULL);
+    }
+    
+    /* Wait until inkey_flag is set */
+}
+
+
+
+/* returns YES if we contain an AngbandView (and hence should direct our events to Angband) */
+static BOOL contains_angband_view(NSView *view)
+{
+    if ([view isKindOfClass:[AngbandView class]]) return YES;
+    for (NSView *subview in [view subviews]) {
+        if (contains_angband_view(subview)) return YES;
+    }
+    return NO;
+}
+
+/* Encodes an NSEvent Angband-style, or forwards it along.  Returns YES if the event was sent to Angband, NO if Cocoa (or nothing) handled it */
+static BOOL send_event(NSEvent *event)
+{
+        
+    /* If the receiving window is not an Angband window, then do nothing */
+    if (! contains_angband_view([[event window] contentView]))
+    {
+        [NSApp sendEvent:event];
+        return NO;
+    }
+    
+    /* Analyze the event */
+    switch ([event type])
+    {
+        case NSKeyDown:
+        {
+            /* Try performing a key equivalent */
+            if ([[NSApp mainMenu] performKeyEquivalent:event]) break;
+            
+            unsigned modifiers = [event modifierFlags];
+            
+            /* Send all NSCommandKeyMasks through */
+            if (modifiers & NSCommandKeyMask)
+            {
+                [NSApp sendEvent:event];
+                break;
+            }
+            
+            if (! [[event characters] length]) break;
+            
+            
+            /* Extract some modifiers */
+            //int mc = !! (modifiers & NSControlKeyMask);
+            //int ms = !! (modifiers & NSShiftKeyMask);
+            //int mo = !! (modifiers & NSAlternateKeyMask);
+            //int mx = !! (modifiers & NSCommandKeyMask);
+            int kp = !! (modifiers & NSNumericPadKeyMask);
+            
+            
+            /* Get the Angband char corresponding to this unichar */
+            unichar c = [[event characters] characterAtIndex:0];
+            char ch;
+            switch (c) {
+                /* Note that NSNumericPadKeyMask is set if any of the arrow
+                 * keys are pressed. We don't want KC_MOD_KEYPAD set for
+                 * those. See #1662 for more details. */
+                case NSUpArrowFunctionKey: ch = ARROW_UP; kp = 0; break;
+                case NSDownArrowFunctionKey: ch = ARROW_DOWN; kp = 0; break;
+                case NSLeftArrowFunctionKey: ch = ARROW_LEFT; kp = 0; break;
+                case NSRightArrowFunctionKey: ch = ARROW_RIGHT; kp = 0; break;
+                case NSF1FunctionKey: ch = KC_F1; break;
+                case NSF2FunctionKey: ch = KC_F2; break;
+                case NSF3FunctionKey: ch = KC_F3; break;
+                case NSF4FunctionKey: ch = KC_F4; break;
+                case NSF5FunctionKey: ch = KC_F5; break;
+                case NSF6FunctionKey: ch = KC_F6; break;
+                case NSF7FunctionKey: ch = KC_F7; break;
+                case NSF8FunctionKey: ch = KC_F8; break;
+                case NSF9FunctionKey: ch = KC_F9; break;
+                case NSF10FunctionKey: ch = KC_F10; break;
+                case NSF11FunctionKey: ch = KC_F11; break;
+                case NSF12FunctionKey: ch = KC_F12; break;
+                case NSF13FunctionKey: ch = KC_F13; break;
+                case NSF14FunctionKey: ch = KC_F14; break;
+                case NSF15FunctionKey: ch = KC_F15; break;
+                case NSHelpFunctionKey: ch = KC_HELP; break;
+                case NSHomeFunctionKey: ch = KC_HOME; break;
+                case NSPageUpFunctionKey: ch = KC_PGUP; break;
+                case NSPageDownFunctionKey: ch = KC_PGDOWN; break;
+                case NSBeginFunctionKey: ch = KC_BEGIN; break;
+                case NSEndFunctionKey: ch = KC_END; break;
+                case NSInsertFunctionKey: ch = KC_INSERT; break;
+                case NSDeleteFunctionKey: ch = KC_DELETE; break;
+                case NSPauseFunctionKey: ch = KC_PAUSE; break;
+                case NSBreakFunctionKey: ch = KC_BREAK; break;
+                    
+                default:
+                    if (c <= 0x7F)
+                        ch = (char)c;
+                    else
+                        ch = '\0';
+                    break;
+            }
+            
+            /* override special keys */
+            switch([event keyCode]) {
+                case kVK_Return: ch = KC_ENTER; break;
+                case kVK_Escape: ch = ESCAPE; break;
+                case kVK_Tab: ch = KC_TAB; break;
+                case kVK_Delete: ch = KC_BACKSPACE; break;
+                case kVK_ANSI_KeypadEnter: ch = KC_ENTER; kp = TRUE; break;
+            }
+
+            /* Hide the mouse pointer */
+            [NSCursor setHiddenUntilMouseMoves:YES];
+            
+            /* Enqueue it */
+            if (ch != '\0')
+            {
+                
+                /* Enqueue the keypress */
+#ifdef KC_MOD_ALT
+                byte mods = 0;
+                if (mo) mods |= KC_MOD_ALT;
+                if (mx) mods |= KC_MOD_META;
+                if (mc && MODS_INCLUDE_CONTROL(ch)) mods |= KC_MOD_CONTROL;
+                if (ms && MODS_INCLUDE_SHIFT(ch)) mods |= KC_MOD_SHIFT;
+                if (kp) mods |= KC_MOD_KEYPAD;
+                Term_keypress(ch, mods);
+#else
+                Term_keypress(ch);
+#endif
+            }
+            
+            break;
+        }
+            
+        case NSLeftMouseDown:
+        {
+            /* Queue mouse presses if they occur in the map section
+             * of the main window.
+             */
+#if 0
+            AngbandContext *angbandContext =
+                [[[event window] contentView] angbandContext];
+            AngbandContext *mainAngbandContext =
+                angband_term[0]->data;
+
+            if (mainAngbandContext->primaryWindow &&
+                [[event window] windowNumber] ==
+                [mainAngbandContext->primaryWindow windowNumber])
+            {
+                int cols, rows, x, y;
+                Term_get_size(&cols, &rows);
+
+                /* Term_mousepress() expects the origin (0,0) at the upper
+                 * left, while locationInWindow puts the origin at the lower
+                 * left.
+                 */
+                NSPoint p = [event locationInWindow];
+                NSSize tileSize = angbandContext->tileSize;
+                x = p.x/(tileSize.width * AngbandScaleIdentity.width);
+                y = rows - p.y/(tileSize.height * AngbandScaleIdentity.height);
+                    
+                /* Sidebar plus border == thirteen characters;
+                 * top row is reserved, and bottom row may have mouse buttons.
+                 * Coordinates run from (0,0) to (cols-1, rows-1).
+                 */
+                if ((x > 13 && x <= cols - 1 &&
+                     y > 0  && y <= rows - 2) ||
+                    (OPT(mouse_buttons) && y == rows - 1 && 
+                     x >= COL_MAP && x < COL_MAP + button_get_length()))
+                {
+                    Term_mousepress(x, y, 1);
+                }
+            }
+#endif
+            /* Pass click through to permit focus change, resize, etc. */
+            [NSApp sendEvent:event];
+            break;
+        }
+
+        case NSApplicationDefined:
+        {
+            if ([event subtype] == AngbandEventWakeup)
+            {
+                return YES;
+            }
+            break;
+        }
+            
+        default:
+            [NSApp sendEvent:event];
+            return YES;
+            break;
+    }
+    return YES;
+}
+
+/*
+ * Check for Events, return TRUE if we process any
+ */
+static BOOL check_events(int wait)
+{ 
+    
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    
+    /* Handles the quit_when_ready flag */
+    if (quit_when_ready) quit_calmly();
+    
+    NSDate* endDate;
+    if (wait == CHECK_EVENTS_WAIT) endDate = [NSDate distantFuture];
+    else endDate = [NSDate distantPast];
+    
+    NSEvent* event;
+    for (;;) {
+        if (quit_when_ready)
+        {
+            /* send escape events until we quit */
+            Term_keypress(0x1B);
+            [pool drain];
+            return false;
+        }
+        else {
+            event = [NSApp nextEventMatchingMask:-1 untilDate:endDate inMode:NSDefaultRunLoopMode dequeue:YES];
+            if (! event)
+            {
+                [pool drain];
+                return FALSE;
+            }
+            if (send_event(event)) break;
+        }
+    }
+    
+    [pool drain];
+    
+    /* Something happened */
+    return YES;
+    
+}
+
+/*
+ * Hook to tell the user something important
+ */
+static void hook_plog(const char * str)
+{
+    if (str)
+    {
+        NSString *string = [NSString stringWithCString:str encoding:NSMacOSRomanStringEncoding];
+        NSRunAlertPanel(@"Danger Will Robinson", @"%@", @"OK", nil, nil, string);
+    }
+}
+
+
+/*
+ * Hook to tell the user something, and then quit
+ */
+static void hook_quit(const char * str)
+{
+    plog(str);
+    exit(0);
+}
+#if 0
+/* Set HFS file type and creator codes on a path */
+static void cocoa_file_open_hook(const char *path, file_type ftype)
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    NSString *pathString = [NSString stringWithUTF8String:path];
+    if (pathString)
+    {   
+        u32b mac_type = 'TEXT';
+        if (ftype == FTYPE_RAW)
+            mac_type = 'DATA';
+        else if (ftype == FTYPE_SAVE)
+            mac_type = 'SAVE';
+        
+        NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLong:mac_type], NSFileHFSTypeCode, [NSNumber numberWithUnsignedLong:ANGBAND_CREATOR], NSFileHFSCreatorCode, nil];
+        [[NSFileManager defaultManager] setAttributes:attrs ofItemAtPath:pathString error:NULL];
+    }
+    [pool drain];
+}
+
+/* A platform-native file save dialogue box, e.g. for saving character dumps */
+static bool cocoa_get_file(const char *suggested_name, char *path, size_t len)
+{
+    NSSavePanel *panel = [NSSavePanel savePanel];
+    NSString *directory = [NSString stringWithCString:ANGBAND_DIR_USER encoding:NSASCIIStringEncoding];
+    NSString *filename = [NSString stringWithCString:suggested_name encoding:NSASCIIStringEncoding];
+
+    if ([panel runModalForDirectory:directory file:filename] == NSOKButton) {
+        const char *p = [[[panel URL] path] UTF8String];
+        my_strcpy(path, p, len);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+#endif
+/*** Main program ***/
+
+@interface AngbandAppDelegate : NSObject {
+    IBOutlet NSMenu *terminalsMenu;
+    NSMenu *_commandMenu;
+    NSDictionary *_commandMenuTagMap;
+}
+
+@property (nonatomic, retain) IBOutlet NSMenu *commandMenu;
+@property (nonatomic, retain) NSDictionary *commandMenuTagMap;
+
+- (IBAction)newGame:sender;
+- (IBAction)editFont:sender;
+- (IBAction)openGame:sender;
+
+- (IBAction)selectWindow: (id)sender;
+
+@end
+
+@implementation AngbandAppDelegate
+
+@synthesize commandMenu=_commandMenu;
+@synthesize commandMenuTagMap=_commandMenuTagMap;
+
+- (IBAction)newGame:sender
+{
+    /* Game is in progress */
+    game_in_progress = TRUE;
+    new_game = TRUE;
+}
+
+- (IBAction)editFont:sender
+{
+    NSFontPanel *panel = [NSFontPanel sharedFontPanel];
+    NSFont *termFont = default_font;
+
+    int i;
+    for (i=0; i < ANGBAND_TERM_MAX; i++) {
+        if ([(id)angband_term[i]->data isMainWindow]) {
+            termFont = [(id)angband_term[i]->data selectionFont];
+            break;
+        }
+    }
+    
+    [panel setPanelFont:termFont isMultiple:NO];
+    [panel orderFront:self];
+}
+
+- (void)changeFont:(id)sender
+{
+    int mainTerm;
+    for (mainTerm=0; mainTerm < ANGBAND_TERM_MAX; mainTerm++) {
+        if ([(id)angband_term[mainTerm]->data isMainWindow]) {
+            break;
+        }
+    }
+
+    /* Bug #1709: Only change font for angband windows */
+    if (mainTerm == ANGBAND_TERM_MAX) return;
+    
+    NSFont *oldFont = default_font;
+    NSFont *newFont = [sender convertFont:oldFont];
+    if (! newFont) return; //paranoia
+    
+    /* Store as the default font if we changed the first term */
+    if (mainTerm == 0) {
+        [newFont retain];
+        [default_font release];
+        default_font = newFont;
+    }
+    
+    /* Record it in the preferences */
+    NSUserDefaults *defs = [NSUserDefaults angbandDefaults];
+    [defs setValue:[newFont fontName] 
+        forKey:[NSString stringWithFormat:@"FontName-%d", mainTerm]];
+    [defs setFloat:[newFont pointSize]
+        forKey:[NSString stringWithFormat:@"FontSize-%d", mainTerm]];
+    [defs synchronize];
+    
+    NSDisableScreenUpdates();
+    
+    /* Update window */
+    AngbandContext *angbandContext = angband_term[mainTerm]->data;
+    [(id)angbandContext setSelectionFont:newFont adjustTerminal: YES];
+    
+    NSEnableScreenUpdates();
+}
+
+- (IBAction)openGame:sender
+{
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    BOOL selectedSomething = NO;
+    int panelResult;
+    NSString* startingDirectory;
+    
+    /* Get where we think the save files are */
+    startingDirectory = [get_data_directory() stringByAppendingPathComponent:@"/save/"];
+    
+    /* Get what we think the default save file name is. Deafult to the empty string. */
+    NSString *savefileName = [[NSUserDefaults angbandDefaults] stringForKey:@"SaveFile"];
+    if (! savefileName) savefileName = @"";
+    
+    /* Set up an open panel */
+    NSOpenPanel* panel = [NSOpenPanel openPanel];
+    [panel setCanChooseFiles:YES];
+    [panel setCanChooseDirectories:NO];
+    [panel setResolvesAliases:YES];
+    [panel setAllowsMultipleSelection:YES];
+    [panel setTreatsFilePackagesAsDirectories:YES];
+    
+    /* Run it */
+    panelResult = [panel runModalForDirectory:startingDirectory file:savefileName types:nil];
+    if (panelResult == NSOKButton)
+    {
+        NSArray* filenames = [panel filenames];
+        if ([filenames count] > 0)
+        {
+            selectedSomething = [[filenames objectAtIndex:0] getFileSystemRepresentation:savefile maxLength:sizeof savefile];
+        }
+    }
+    
+    if (selectedSomething)
+    {
+        
+        /* Remember this so we can select it by default next time */
+        record_current_savefile();
+        
+        /* Game is in progress */
+        game_in_progress = TRUE;
+        new_game = FALSE;
+    }
+    
+    [pool drain];
+}
+
+- (IBAction)saveGame:sender
+{
+    /* Hack -- Forget messages */
+    msg_flag = FALSE;
+    
+    /* Save the game */
+    do_cmd_save_game(FALSE);
+    
+    /* Record the current save file so we can select it by default next time. It's a little sketchy that this only happens when we save through the menu; ideally game-triggered saves would trigger it too. */
+    record_current_savefile();
+}
+
+- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
+{
+    SEL sel = [menuItem action];
+    NSInteger tag = [menuItem tag];
+
+    if( tag >= AngbandWindowMenuItemTagBase && tag < AngbandWindowMenuItemTagBase + ANGBAND_TERM_MAX )
+    {
+        if( tag == AngbandWindowMenuItemTagBase )
+        {
+            // the main window should always be available and visible
+            return YES;
+        }
+        else
+        {
+            NSInteger subwindowNumber = tag - AngbandWindowMenuItemTagBase;
+            return (window_flag[subwindowNumber] > 0);
+        }
+
+        return NO;
+    }
+
+    if (sel == @selector(newGame:))
+    {
+        return ! game_in_progress;
+    }
+    else if (sel == @selector(editFont:))
+    {
+        return YES;
+    }
+    else if (sel == @selector(openGame:))
+    {
+        return ! game_in_progress;
+    }
+    else if (sel == @selector(setRefreshRate:) && [superitem(menuItem) tag] == 150)
+    {
+        NSInteger fps = [[NSUserDefaults standardUserDefaults] integerForKey: @"FramesPerSecond"];
+        [menuItem setState: ([menuItem tag] == fps)];
+        return YES;
+    }
+    else if( sel == @selector(setGraphicsMode:) )
+    {
+        NSInteger requestedGraphicsMode = [[NSUserDefaults standardUserDefaults] integerForKey: @"GraphicsID"];
+        [menuItem setState: (tag == requestedGraphicsMode)];
+        return YES;
+    }
+    else if( sel == @selector(sendAngbandCommand:) )
+    {
+        // we only want to be able to send commands during an active game
+        return !!game_in_progress;
+    }
+    else return YES;
+}
+
+
+- (IBAction)setRefreshRate:(NSMenuItem *)menuItem
+{
+    frames_per_second = [menuItem tag];
+    [[NSUserDefaults angbandDefaults] setInteger:frames_per_second forKey:@"FramesPerSecond"];
+}
+
+- (IBAction)selectWindow: (id)sender
+{
+    NSInteger subwindowNumber = [(NSMenuItem *)sender tag] - AngbandWindowMenuItemTagBase;
+    AngbandContext *context = angband_term[subwindowNumber]->data;
+    [context->primaryWindow makeKeyAndOrderFront: self];
+}
+
+- (void)prepareWindowsMenu
+{
+    // get the window menu with default items and add a separator and item for the main window
+    NSMenu *windowsMenu = [[NSApplication sharedApplication] windowsMenu];
+    [windowsMenu addItem: [NSMenuItem separatorItem]];
+
+    NSMenuItem *angbandItem = [[NSMenuItem alloc] initWithTitle: @"PosChengband" action: @selector(selectWindow:) keyEquivalent: @"0"];
+    [angbandItem setTarget: self];
+    [angbandItem setTag: AngbandWindowMenuItemTagBase];
+    [windowsMenu addItem: angbandItem];
+    [angbandItem release];
+
+    // add items for the additional term windows
+    for( NSInteger i = 1; i < ANGBAND_TERM_MAX; i++ )
+    {
+        NSString *title = [NSString stringWithFormat: @"Term %ld", (long)i];
+        NSMenuItem *windowItem = [[NSMenuItem alloc] initWithTitle: title action: @selector(selectWindow:) keyEquivalent: @""];
+        [windowItem setTarget: self];
+        [windowItem setTag: AngbandWindowMenuItemTagBase + i];
+        [windowsMenu addItem: windowItem];
+        [windowItem release];
+    }
+}
+
+/**
+ *  Send a command to Angband via a menu item. This places the appropriate key down events into the queue
+ *  so that it seems like the user pressed them (instead of trying to use the term directly).
+ */
+- (void)sendAngbandCommand: (id)sender
+{
+    NSMenuItem *menuItem = (NSMenuItem *)sender;
+    NSString *command = [self.commandMenuTagMap objectForKey: @([menuItem tag])];
+    NSInteger windowNumber = [((AngbandContext *)angband_term[0]->data)->primaryWindow windowNumber];
+
+    // send a \ to bypass keymaps
+    NSEvent *escape = [NSEvent keyEventWithType: NSKeyDown
+                                       location: NSZeroPoint
+                                  modifierFlags: 0
+                                      timestamp: 0.0
+                                   windowNumber: windowNumber
+                                        context: nil
+                                     characters: @"\\"
+                    charactersIgnoringModifiers: @"\\"
+                                      isARepeat: NO
+                                        keyCode: 0];
+    [[NSApplication sharedApplication] postEvent: escape atStart: NO];
+
+    // send the actual command (from the original command set)
+    NSEvent *keyDown = [NSEvent keyEventWithType: NSKeyDown
+                                        location: NSZeroPoint
+                                   modifierFlags: 0
+                                       timestamp: 0.0
+                                    windowNumber: windowNumber
+                                         context: nil
+                                      characters: command
+                     charactersIgnoringModifiers: command
+                                       isARepeat: NO
+                                         keyCode: 0];
+    [[NSApplication sharedApplication] postEvent: keyDown atStart: NO];
+}
+
+/**
+ *  Set up the command menu dynamically, based on CommandMenu.plist.
+ */
+- (void)prepareCommandMenu
+{
+    NSString *commandMenuPath = [[NSBundle mainBundle] pathForResource: @"CommandMenu" ofType: @"plist"];
+    NSArray *commandMenuItems = [[NSArray alloc] initWithContentsOfFile: commandMenuPath];
+    NSMutableDictionary *angbandCommands = [[NSMutableDictionary alloc] init];
+    NSInteger tagOffset = 0;
+
+    for( NSDictionary *item in commandMenuItems )
+    {
+        BOOL useShiftModifier = [[item valueForKey: @"ShiftModifier"] boolValue];
+        BOOL useOptionModifier = [[item valueForKey: @"OptionModifier"] boolValue];
+        NSUInteger keyModifiers = NSCommandKeyMask;
+        keyModifiers |= (useShiftModifier) ? NSShiftKeyMask : 0;
+        keyModifiers |= (useOptionModifier) ? NSAlternateKeyMask : 0;
+
+        NSString *title = [item valueForKey: @"Title"];
+        NSString *key = [item valueForKey: @"KeyEquivalent"];
+        NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle: title action: @selector(sendAngbandCommand:) keyEquivalent: key];
+        [menuItem setTarget: self];
+        [menuItem setKeyEquivalentModifierMask: keyModifiers];
+        [menuItem setTag: AngbandCommandMenuItemTagBase + tagOffset];
+        [self.commandMenu addItem: menuItem];
+        [menuItem release];
+
+        NSString *angbandCommand = [item valueForKey: @"AngbandCommand"];
+        [angbandCommands setObject: angbandCommand forKey: @([menuItem tag])];
+        tagOffset++;
+    }
+
+    [commandMenuItems release];
+
+    NSDictionary *safeCommands = [[NSDictionary alloc] initWithDictionary: angbandCommands];
+    self.commandMenuTagMap = safeCommands;
+    [safeCommands release];
+    [angbandCommands release];
+}
+
+- (void)awakeFromNib
+{
+    [super awakeFromNib];
+
+    [self prepareWindowsMenu];
+    [self prepareCommandMenu];
+}
+
+- (void)applicationDidFinishLaunching:sender
+{
+    [AngbandContext beginGame];
+    
+    //once beginGame finished, the game is over - that's how Angband works, and we should quit
+    game_is_finished = TRUE;
+    [NSApp terminate:self];
+}
+
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
+{
+    if (p_ptr->playing == FALSE || game_is_finished == TRUE)
+    {
+        return NSTerminateNow;
+    }
+    else if (! inkey_flag)
+    {
+        /* For compatibility with other ports, do not quit in this case */
+        return NSTerminateCancel;
+    }
+    else
+    {
+      //cmd_insert(CMD_QUIT);
+        /* Post an escape event so that we can return from our get-key-event function */
+        wakeup_event_loop();
+        quit_when_ready = true;
+        // must return Cancel, not Later, because we need to get out of the run loop and back to Angband's loop
+        return NSTerminateCancel;
+    }
+}
+
+/* Dynamically build the Graphics menu */
+- (void)menuNeedsUpdate:(NSMenu *)menu {
+    
+    /* Only the graphics menu is dynamic */
+    //if (! [[menu title] isEqualToString:@"Graphics"])
+        return;
+#if 0    
+    /* If it's non-empty, then we've already built it. Currently graphics modes won't change once created; if they ever can we can remove this check.
+       Note that the check mark does change, but that's handled in validateMenuItem: instead of menuNeedsUpdate: */
+    if ([menu numberOfItems] > 0)
+        return;
+    
+    /* This is the action for all these menu items */
+    SEL action = @selector(setGraphicsMode:);
+    
+    /* Add an initial Classic ASCII menu item */
+    NSMenuItem *item = [menu addItemWithTitle:@"Classic ASCII" action:action keyEquivalent:@""];
+    [item setTag:GRAPHICS_NONE];
+    
+    /* Walk through the list of graphics modes */
+    NSInteger i;
+    for (i=0; graphics_modes[i].pNext; i++)
+    {
+        const graphics_mode *graf = &graphics_modes[i];
+        
+        /* Make the title. NSMenuItem throws on a nil title, so ensure it's not nil. */
+        NSString *title = [[NSString alloc] initWithUTF8String:graf->menuname];
+        if (! title) title = [@"(Unknown)" copy];
+        
+        /* Make the item */
+        NSMenuItem *item = [menu addItemWithTitle:title action:action keyEquivalent:@""];
+        [item setTag:graf->grafID];
+    }
+#endif
+}
+
+/* Delegate method that gets called if we're asked to open a file. */
+- (BOOL)application:(NSApplication *)sender openFiles:(NSArray *)filenames
+{
+    /* Can't open a file once we've started */
+    if (game_in_progress) return NO;
+    
+    /* We can only open one file. Use the last one. */
+    NSString *file = [filenames lastObject];
+    if (! file) return NO;
+    
+    /* Put it in savefile */
+    if (! [file getFileSystemRepresentation:savefile maxLength:sizeof savefile]) return NO;
+    
+    /* Success, remember to load it */
+    //cmd.command = CMD_LOADFILE;
+    
+    /* Wake us up in case this arrives while we're sitting at the Welcome screen! */
+    wakeup_event_loop();
+    
+    return YES;
+}
+
+@end
+
+int main(int argc, char* argv[])
+{
+    NSApplicationMain(argc, (void*)argv);    
+    return (0);
+}
+
+#endif /* MACINTOSH || MACH_O_CARBON */