├── screenshot.png
├── SwiftWadReader.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── terhechte.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
├── xcuserdata
│ └── terhechte.xcuserdatad
│ │ ├── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── SwiftWadReader.xcscheme
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
└── project.pbxproj
├── README.md
└── SwiftWadReader
├── Assets.xcassets
└── AppIcon.appiconset
│ └── Contents.json
├── Info.plist
├── WadReader.swift
├── AppDelegate.swift
└── Base.lproj
└── MainMenu.xib
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terhechte/SwiftWadReader/HEAD/screenshot.png
--------------------------------------------------------------------------------
/SwiftWadReader.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SwiftWadReader.xcodeproj/project.xcworkspace/xcuserdata/terhechte.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terhechte/SwiftWadReader/HEAD/SwiftWadReader.xcodeproj/project.xcworkspace/xcuserdata/terhechte.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Swift WAD Reader
2 |
3 | This is a simple example to showcase how to use the new `Data` type in Swift 3 to read binary data from a file into the correct structures in memory.
4 |
5 | There's an accompagniying blog post on [appventure.me](http://appventure.me). The will read an Doom WAD file and parse it in order to display a couple of the items (*Lumps*, in Doom parlance). If you don't have a Doom WAD file handy, the app can download one for you automatically.
6 |
7 | Here's a screenshot.
8 |
9 | 
10 |
11 | Have fun
12 |
13 | You can find me on Twitter as [@terhechte](http://twitter.com/terhechte)
14 |
15 |
--------------------------------------------------------------------------------
/SwiftWadReader.xcodeproj/xcuserdata/terhechte.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SwiftWadReader.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 4D9BB9321D393AE300513B51
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/SwiftWadReader.xcodeproj/xcuserdata/terhechte.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/SwiftWadReader/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/SwiftWadReader/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSMinimumSystemVersion
26 | $(MACOSX_DEPLOYMENT_TARGET)
27 | NSHumanReadableCopyright
28 | Copyright © 2016 Benedikt Terhechte. All rights reserved.
29 | NSMainNibFile
30 | MainMenu
31 | NSAppTransportSecurity
32 |
33 | NSExceptionDomains
34 |
35 | distro.ibiblio.org
36 |
37 | NSExceptionAllowsInsecureHTTPLoads
38 |
39 |
40 |
41 |
42 | NSPrincipalClass
43 | NSApplication
44 |
45 |
46 |
--------------------------------------------------------------------------------
/SwiftWadReader.xcodeproj/xcuserdata/terhechte.xcuserdatad/xcschemes/SwiftWadReader.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/SwiftWadReader/WadReader.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WadReader.swift
3 | // SwiftWadReader
4 | //
5 | // Created by Benedikt Terhechte on 15/07/16.
6 | // Copyright © 2016 Benedikt Terhechte. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // FIXME: Seperate File
12 |
13 | extension Data {
14 | func scanValue(start: Int, length: Int) -> T {
15 | return self.subdata(in: start..) -> T in
17 | return pointer.pointee
18 | }
19 | }
20 | }
21 |
22 | public enum WadReaderError: Error {
23 | case invalidWadFile(reason: String)
24 | case invalidLup(reason: String)
25 | }
26 |
27 | public struct Lump {
28 | public let filepos: Int32
29 | public let size: Int32
30 | public let name: String
31 | }
32 |
33 | public class WadReader {
34 |
35 | /// The lumps that were parsed out of the wad file
36 | private var lumps: [Lump] = []
37 |
38 | /// The MMapped contents of the Wad file
39 | private let data: Data
40 |
41 | private var numberOfLumps: Int32 = 0
42 |
43 | private var directoryLocation: Int32 = 0
44 |
45 | public init(wadFile file: URL) throws {
46 | data = try Data(contentsOf: file, options: .alwaysMapped)
47 | }
48 |
49 | public func parse() throws -> [Lump] {
50 | try validateWadFile()
51 | try parseWadFile()
52 | return lumps
53 | }
54 |
55 | /**
56 | Validate the contents of the wad file by inspecting the header.
57 | See http://doom.wikia.com/wiki/WAD
58 | and http://doomlegacy.sourceforge.net/hosted/doomspec1666.txt
59 | */
60 | public func validateWadFile() throws {
61 | // Several Wad File definitions
62 | let wadMaxSize = 12, wadLumpsStart = 4, wadDirectoryStart = 8, wadDefSize = 4
63 |
64 | // A WAD file always starts with a 12-byte header.
65 | guard data.count >= wadMaxSize else { throw WadReaderError.invalidWadFile(reason: "File is too small") }
66 |
67 | // It contains three values:
68 |
69 | // The ASCII characters "IWAD" or "PWAD". Defines whether the WAD is an IWAD or a PWAD.
70 | let validStart = "IWAD".data(using: String.Encoding.ascii)!
71 | guard data.subdata(in: 0.. 0 && directoryInteger > Int32(wadMaxSize)
81 | else {
82 | throw WadReaderError.invalidWadFile(reason: "Empty Wad File")
83 | }
84 |
85 | directoryLocation = directoryInteger
86 | numberOfLumps = lumpsInteger
87 | }
88 |
89 | /**
90 | Parse the list of lumps in the wad file
91 | */
92 | public func parseWadFile() throws {
93 | let wadDirectoryEntrySize = 16
94 |
95 | // The directory associates names of lumps with the data that belong to them. It consists of a number of entries, each with a length of 16 bytes. The length of the directory is determined by the number given in the WAD header.
96 | let directory = data.subdata(in: Int(directoryLocation)..<(Int(directoryLocation) + Int(numberOfLumps) * wadDirectoryEntrySize))
97 |
98 | var floorsStarted = false
99 |
100 | for currentIndex in stride(from: 0, to: directory.count, by: wadDirectoryEntrySize) {
101 |
102 | let currentDirectoryEntry = directory.subdata(in: currentIndex..) -> String? in
115 | var localPointer = pointer
116 | for _ in 0..<8 {
117 | guard localPointer.pointee != CChar(0) else { break }
118 | localPointer = localPointer.successor()
119 | }
120 | let position = pointer.distance(to: localPointer)
121 | return String(data: nameData.subdata(in: 0.. () {
108 | progressBar.doubleValue = progress.fractionCompleted
109 | progressLabel.stringValue = progress.localizedDescription
110 | }
111 |
112 | fileprivate func userError(withMessage message: String) {
113 | let alert = NSAlert()
114 | alert.messageText = message
115 | alert.informativeText = "There was an error"
116 | alert.beginSheetModal(for: self.window, completionHandler: nil)
117 | }
118 |
119 | }
120 |
121 | // MARK: UI
122 |
123 | extension AppDelegate {
124 | @IBAction func downloadWadFile(sender: AnyObject) {
125 |
126 | state = .loading
127 |
128 | progress.addObserver(self, forKeyPath: Keys.ProgressFractionCompleted, options: [], context: &Keys.ProgressFractionCompleted)
129 | progress.addObserver(self, forKeyPath: Keys.ProgressLocalizedDescription, options: [], context: &Keys.ProgressLocalizedDescription)
130 |
131 | let session = URLSession(configuration: URLSessionConfiguration.ephemeral, delegate: self, delegateQueue: OperationQueue.main)
132 |
133 | session.downloadTask(with: URL.WadFileURL).resume()
134 | }
135 |
136 | @IBAction func openWadFile(sender: AnyObject) {
137 | let dialog = NSOpenPanel()
138 | dialog.allowedFileTypes = ["wad"]
139 | dialog.beginSheetModal(for: self.window, completionHandler: { (result: Int) -> Void in
140 | guard result == NSFileHandlingPanelOKButton,
141 | let url = dialog.url,
142 | FileManager.default.fileExists(atPath: url.path)
143 | else { return }
144 |
145 | self.handleWADFile(url: url)
146 |
147 | if self.state == .loaded {
148 | // store the successful location
149 | UserDefaults.standard.set(url, forKey: Keys.UserDefaultsWadFileURL)
150 | }
151 |
152 | })
153 | }
154 | }
155 |
156 | // MARK: TableView
157 |
158 | extension AppDelegate: NSTableViewDataSource {
159 | public func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
160 | return lumps[row].name as NSString
161 | }
162 |
163 | public func numberOfRows(in tableView: NSTableView) -> Int {
164 | return lumps.count
165 | }
166 | }
167 |
168 | // MARK: Networking
169 |
170 | extension AppDelegate: URLSessionDownloadDelegate {
171 |
172 | func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
173 | if let error = error {
174 | userError(withMessage: error.localizedDescription)
175 | state = .unloaded
176 | }
177 | }
178 |
179 | func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
180 | progress.totalUnitCount = 0
181 | progress.completedUnitCount = 0
182 | progress.removeObserver(self, forKeyPath: Keys.ProgressLocalizedDescription)
183 | progress.removeObserver(self, forKeyPath: Keys.ProgressFractionCompleted)
184 | state = .loaded
185 | handleWADFile(url: location)
186 | }
187 |
188 | func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
189 | print(totalBytesWritten, totalBytesWritten)
190 | progress.totalUnitCount = totalBytesExpectedToWrite
191 | progress.completedUnitCount = totalBytesWritten
192 |
193 | }
194 | }
195 |
196 |
--------------------------------------------------------------------------------
/SwiftWadReader.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 4D9BB9371D393AE300513B51 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D9BB9361D393AE300513B51 /* AppDelegate.swift */; };
11 | 4D9BB9391D393AE300513B51 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4D9BB9381D393AE300513B51 /* Assets.xcassets */; };
12 | 4D9BB93C1D393AE300513B51 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4D9BB93A1D393AE300513B51 /* MainMenu.xib */; };
13 | 4D9BB9441D393AF100513B51 /* WadReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D9BB9431D393AF100513B51 /* WadReader.swift */; };
14 | /* End PBXBuildFile section */
15 |
16 | /* Begin PBXFileReference section */
17 | 4D9BB9331D393AE300513B51 /* SwiftWadReader.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftWadReader.app; sourceTree = BUILT_PRODUCTS_DIR; };
18 | 4D9BB9361D393AE300513B51 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
19 | 4D9BB9381D393AE300513B51 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
20 | 4D9BB93B1D393AE300513B51 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; };
21 | 4D9BB93D1D393AE300513B51 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
22 | 4D9BB9431D393AF100513B51 /* WadReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WadReader.swift; sourceTree = ""; };
23 | /* End PBXFileReference section */
24 |
25 | /* Begin PBXFrameworksBuildPhase section */
26 | 4D9BB9301D393AE300513B51 /* Frameworks */ = {
27 | isa = PBXFrameworksBuildPhase;
28 | buildActionMask = 2147483647;
29 | files = (
30 | );
31 | runOnlyForDeploymentPostprocessing = 0;
32 | };
33 | /* End PBXFrameworksBuildPhase section */
34 |
35 | /* Begin PBXGroup section */
36 | 4D9BB92A1D393AE200513B51 = {
37 | isa = PBXGroup;
38 | children = (
39 | 4D9BB9351D393AE300513B51 /* SwiftWadReader */,
40 | 4D9BB9341D393AE300513B51 /* Products */,
41 | );
42 | sourceTree = "";
43 | };
44 | 4D9BB9341D393AE300513B51 /* Products */ = {
45 | isa = PBXGroup;
46 | children = (
47 | 4D9BB9331D393AE300513B51 /* SwiftWadReader.app */,
48 | );
49 | name = Products;
50 | sourceTree = "";
51 | };
52 | 4D9BB9351D393AE300513B51 /* SwiftWadReader */ = {
53 | isa = PBXGroup;
54 | children = (
55 | 4D9BB9361D393AE300513B51 /* AppDelegate.swift */,
56 | 4D9BB9381D393AE300513B51 /* Assets.xcassets */,
57 | 4D9BB93A1D393AE300513B51 /* MainMenu.xib */,
58 | 4D9BB93D1D393AE300513B51 /* Info.plist */,
59 | 4D9BB9431D393AF100513B51 /* WadReader.swift */,
60 | );
61 | path = SwiftWadReader;
62 | sourceTree = "";
63 | };
64 | /* End PBXGroup section */
65 |
66 | /* Begin PBXNativeTarget section */
67 | 4D9BB9321D393AE300513B51 /* SwiftWadReader */ = {
68 | isa = PBXNativeTarget;
69 | buildConfigurationList = 4D9BB9401D393AE300513B51 /* Build configuration list for PBXNativeTarget "SwiftWadReader" */;
70 | buildPhases = (
71 | 4D9BB92F1D393AE300513B51 /* Sources */,
72 | 4D9BB9301D393AE300513B51 /* Frameworks */,
73 | 4D9BB9311D393AE300513B51 /* Resources */,
74 | );
75 | buildRules = (
76 | );
77 | dependencies = (
78 | );
79 | name = SwiftWadReader;
80 | productName = SwiftWadReader;
81 | productReference = 4D9BB9331D393AE300513B51 /* SwiftWadReader.app */;
82 | productType = "com.apple.product-type.application";
83 | };
84 | /* End PBXNativeTarget section */
85 |
86 | /* Begin PBXProject section */
87 | 4D9BB92B1D393AE200513B51 /* Project object */ = {
88 | isa = PBXProject;
89 | attributes = {
90 | LastSwiftUpdateCheck = 0800;
91 | LastUpgradeCheck = 0800;
92 | ORGANIZATIONNAME = "Benedikt Terhechte";
93 | TargetAttributes = {
94 | 4D9BB9321D393AE300513B51 = {
95 | CreatedOnToolsVersion = 8.0;
96 | DevelopmentTeam = 76VT9VZ6GK;
97 | DevelopmentTeamName = "Benedikt Terhechte";
98 | ProvisioningStyle = Automatic;
99 | };
100 | };
101 | };
102 | buildConfigurationList = 4D9BB92E1D393AE200513B51 /* Build configuration list for PBXProject "SwiftWadReader" */;
103 | compatibilityVersion = "Xcode 3.2";
104 | developmentRegion = English;
105 | hasScannedForEncodings = 0;
106 | knownRegions = (
107 | en,
108 | Base,
109 | );
110 | mainGroup = 4D9BB92A1D393AE200513B51;
111 | productRefGroup = 4D9BB9341D393AE300513B51 /* Products */;
112 | projectDirPath = "";
113 | projectRoot = "";
114 | targets = (
115 | 4D9BB9321D393AE300513B51 /* SwiftWadReader */,
116 | );
117 | };
118 | /* End PBXProject section */
119 |
120 | /* Begin PBXResourcesBuildPhase section */
121 | 4D9BB9311D393AE300513B51 /* Resources */ = {
122 | isa = PBXResourcesBuildPhase;
123 | buildActionMask = 2147483647;
124 | files = (
125 | 4D9BB9391D393AE300513B51 /* Assets.xcassets in Resources */,
126 | 4D9BB93C1D393AE300513B51 /* MainMenu.xib in Resources */,
127 | );
128 | runOnlyForDeploymentPostprocessing = 0;
129 | };
130 | /* End PBXResourcesBuildPhase section */
131 |
132 | /* Begin PBXSourcesBuildPhase section */
133 | 4D9BB92F1D393AE300513B51 /* Sources */ = {
134 | isa = PBXSourcesBuildPhase;
135 | buildActionMask = 2147483647;
136 | files = (
137 | 4D9BB9371D393AE300513B51 /* AppDelegate.swift in Sources */,
138 | 4D9BB9441D393AF100513B51 /* WadReader.swift in Sources */,
139 | );
140 | runOnlyForDeploymentPostprocessing = 0;
141 | };
142 | /* End PBXSourcesBuildPhase section */
143 |
144 | /* Begin PBXVariantGroup section */
145 | 4D9BB93A1D393AE300513B51 /* MainMenu.xib */ = {
146 | isa = PBXVariantGroup;
147 | children = (
148 | 4D9BB93B1D393AE300513B51 /* Base */,
149 | );
150 | name = MainMenu.xib;
151 | sourceTree = "";
152 | };
153 | /* End PBXVariantGroup section */
154 |
155 | /* Begin XCBuildConfiguration section */
156 | 4D9BB93E1D393AE300513B51 /* Debug */ = {
157 | isa = XCBuildConfiguration;
158 | buildSettings = {
159 | ALWAYS_SEARCH_USER_PATHS = NO;
160 | CLANG_ANALYZER_NONNULL = YES;
161 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
162 | CLANG_CXX_LIBRARY = "libc++";
163 | CLANG_ENABLE_MODULES = YES;
164 | CLANG_ENABLE_OBJC_ARC = YES;
165 | CLANG_WARN_BOOL_CONVERSION = YES;
166 | CLANG_WARN_CONSTANT_CONVERSION = YES;
167 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
168 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
169 | CLANG_WARN_EMPTY_BODY = YES;
170 | CLANG_WARN_ENUM_CONVERSION = YES;
171 | CLANG_WARN_INT_CONVERSION = YES;
172 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
173 | CLANG_WARN_UNREACHABLE_CODE = YES;
174 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
175 | CODE_SIGN_IDENTITY = "-";
176 | COPY_PHASE_STRIP = NO;
177 | DEBUG_INFORMATION_FORMAT = dwarf;
178 | ENABLE_STRICT_OBJC_MSGSEND = YES;
179 | ENABLE_TESTABILITY = YES;
180 | GCC_C_LANGUAGE_STANDARD = gnu99;
181 | GCC_DYNAMIC_NO_PIC = NO;
182 | GCC_NO_COMMON_BLOCKS = YES;
183 | GCC_OPTIMIZATION_LEVEL = 0;
184 | GCC_PREPROCESSOR_DEFINITIONS = (
185 | "DEBUG=1",
186 | "$(inherited)",
187 | );
188 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
189 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
190 | GCC_WARN_UNDECLARED_SELECTOR = YES;
191 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
192 | GCC_WARN_UNUSED_FUNCTION = YES;
193 | GCC_WARN_UNUSED_VARIABLE = YES;
194 | MACOSX_DEPLOYMENT_TARGET = 10.11;
195 | MTL_ENABLE_DEBUG_INFO = YES;
196 | ONLY_ACTIVE_ARCH = YES;
197 | SDKROOT = macosx;
198 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
199 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
200 | };
201 | name = Debug;
202 | };
203 | 4D9BB93F1D393AE300513B51 /* Release */ = {
204 | isa = XCBuildConfiguration;
205 | buildSettings = {
206 | ALWAYS_SEARCH_USER_PATHS = NO;
207 | CLANG_ANALYZER_NONNULL = YES;
208 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
209 | CLANG_CXX_LIBRARY = "libc++";
210 | CLANG_ENABLE_MODULES = YES;
211 | CLANG_ENABLE_OBJC_ARC = YES;
212 | CLANG_WARN_BOOL_CONVERSION = YES;
213 | CLANG_WARN_CONSTANT_CONVERSION = YES;
214 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
215 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
216 | CLANG_WARN_EMPTY_BODY = YES;
217 | CLANG_WARN_ENUM_CONVERSION = YES;
218 | CLANG_WARN_INT_CONVERSION = YES;
219 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
220 | CLANG_WARN_UNREACHABLE_CODE = YES;
221 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
222 | CODE_SIGN_IDENTITY = "-";
223 | COPY_PHASE_STRIP = NO;
224 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
225 | ENABLE_NS_ASSERTIONS = NO;
226 | ENABLE_STRICT_OBJC_MSGSEND = YES;
227 | GCC_C_LANGUAGE_STANDARD = gnu99;
228 | GCC_NO_COMMON_BLOCKS = YES;
229 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
230 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
231 | GCC_WARN_UNDECLARED_SELECTOR = YES;
232 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
233 | GCC_WARN_UNUSED_FUNCTION = YES;
234 | GCC_WARN_UNUSED_VARIABLE = YES;
235 | MACOSX_DEPLOYMENT_TARGET = 10.11;
236 | MTL_ENABLE_DEBUG_INFO = NO;
237 | SDKROOT = macosx;
238 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
239 | };
240 | name = Release;
241 | };
242 | 4D9BB9411D393AE300513B51 /* Debug */ = {
243 | isa = XCBuildConfiguration;
244 | buildSettings = {
245 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
246 | COMBINE_HIDPI_IMAGES = YES;
247 | INFOPLIST_FILE = SwiftWadReader/Info.plist;
248 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
249 | PRODUCT_BUNDLE_IDENTIFIER = com.stylemac.SwiftWadReader;
250 | PRODUCT_NAME = "$(TARGET_NAME)";
251 | SWIFT_VERSION = 3.0;
252 | };
253 | name = Debug;
254 | };
255 | 4D9BB9421D393AE300513B51 /* Release */ = {
256 | isa = XCBuildConfiguration;
257 | buildSettings = {
258 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
259 | COMBINE_HIDPI_IMAGES = YES;
260 | INFOPLIST_FILE = SwiftWadReader/Info.plist;
261 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
262 | PRODUCT_BUNDLE_IDENTIFIER = com.stylemac.SwiftWadReader;
263 | PRODUCT_NAME = "$(TARGET_NAME)";
264 | SWIFT_VERSION = 3.0;
265 | };
266 | name = Release;
267 | };
268 | /* End XCBuildConfiguration section */
269 |
270 | /* Begin XCConfigurationList section */
271 | 4D9BB92E1D393AE200513B51 /* Build configuration list for PBXProject "SwiftWadReader" */ = {
272 | isa = XCConfigurationList;
273 | buildConfigurations = (
274 | 4D9BB93E1D393AE300513B51 /* Debug */,
275 | 4D9BB93F1D393AE300513B51 /* Release */,
276 | );
277 | defaultConfigurationIsVisible = 0;
278 | defaultConfigurationName = Release;
279 | };
280 | 4D9BB9401D393AE300513B51 /* Build configuration list for PBXNativeTarget "SwiftWadReader" */ = {
281 | isa = XCConfigurationList;
282 | buildConfigurations = (
283 | 4D9BB9411D393AE300513B51 /* Debug */,
284 | 4D9BB9421D393AE300513B51 /* Release */,
285 | );
286 | defaultConfigurationIsVisible = 0;
287 | };
288 | /* End XCConfigurationList section */
289 | };
290 | rootObject = 4D9BB92B1D393AE200513B51 /* Project object */;
291 | }
292 |
--------------------------------------------------------------------------------
/SwiftWadReader/Base.lproj/MainMenu.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 | NSNegateBoolean
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
--------------------------------------------------------------------------------