Added basic UICollectionView-based UI for selecting games
This commit is contained in:
parent
f77d16c9ce
commit
59fe9b0480
137
Common/Collection View/GameCollectionViewCell.swift
Normal file
137
Common/Collection View/GameCollectionViewCell.swift
Normal file
@ -0,0 +1,137 @@
|
||||
//
|
||||
// GameCollectionViewCell.swift
|
||||
// Delta
|
||||
//
|
||||
// Created by Riley Testut on 10/21/15.
|
||||
// Copyright © 2015 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class GameCollectionViewCell: UICollectionViewCell
|
||||
{
|
||||
let imageView = BoxArtImageView()
|
||||
let nameLabel = UILabel()
|
||||
|
||||
private var maximumBoxArtSize: CGSize = CGSize(width: 100, height: 100) {
|
||||
didSet
|
||||
{
|
||||
self.imageViewWidthConstraint.constant = self.maximumBoxArtSize.width
|
||||
self.imageViewHeightConstraint.constant = self.maximumBoxArtSize.height
|
||||
|
||||
self.nameLabelVerticalSpacingConstraint.constant = self.maximumBoxArtSize.height / 20.0
|
||||
self.nameLabelFocusedVerticalSpacingConstraint?.constant = self.maximumBoxArtSize.height / 20.0
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private var imageViewWidthConstraint: NSLayoutConstraint!
|
||||
private var imageViewHeightConstraint: NSLayoutConstraint!
|
||||
|
||||
private var nameLabelBottomAnchorConstraint: NSLayoutConstraint!
|
||||
|
||||
private var nameLabelVerticalSpacingConstraint: NSLayoutConstraint!
|
||||
private var nameLabelFocusedVerticalSpacingConstraint: NSLayoutConstraint?
|
||||
|
||||
override init(frame: CGRect)
|
||||
{
|
||||
super.init(frame: frame)
|
||||
|
||||
self.configureSubviews()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder)
|
||||
{
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
self.configureSubviews()
|
||||
}
|
||||
|
||||
private func configureSubviews()
|
||||
{
|
||||
// Fix super annoying Unsatisfiable Constraints message in debugger
|
||||
self.contentView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
self.imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.contentView.addSubview(self.imageView)
|
||||
|
||||
self.nameLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.nameLabel.font = UIFont.boldSystemFontOfSize(12)
|
||||
self.nameLabel.textAlignment = .Center
|
||||
self.nameLabel.numberOfLines = 0
|
||||
self.contentView.addSubview(self.nameLabel)
|
||||
|
||||
|
||||
// Auto Layout
|
||||
|
||||
self.imageView.leadingAnchor.constraintEqualToAnchor(self.contentView.leadingAnchor).active = true
|
||||
self.imageView.trailingAnchor.constraintEqualToAnchor(self.contentView.trailingAnchor).active = true
|
||||
self.imageView.topAnchor.constraintEqualToAnchor(self.contentView.topAnchor).active = true
|
||||
|
||||
let verticalSpacingConstant = self.maximumBoxArtSize.height / 20.0
|
||||
|
||||
self.nameLabelVerticalSpacingConstraint = self.nameLabel.topAnchor.constraintEqualToAnchor(self.imageView.bottomAnchor, constant: verticalSpacingConstant)
|
||||
|
||||
#if os(tvOS)
|
||||
|
||||
self.nameLabelVerticalSpacingConstraint.active = false
|
||||
|
||||
self.nameLabelFocusedVerticalSpacingConstraint = self.nameLabel.topAnchor.constraintEqualToAnchor(self.imageView.focusedFrameGuide.bottomAnchor, constant: verticalSpacingConstant)
|
||||
self.nameLabelFocusedVerticalSpacingConstraint?.active = true
|
||||
#else
|
||||
self.nameLabelVerticalSpacingConstraint.active = true
|
||||
#endif
|
||||
|
||||
self.nameLabel.leadingAnchor.constraintEqualToAnchor(self.contentView.leadingAnchor).active = true
|
||||
self.nameLabel.trailingAnchor.constraintEqualToAnchor(self.contentView.trailingAnchor).active = true
|
||||
|
||||
self.nameLabelBottomAnchorConstraint = self.nameLabel.bottomAnchor.constraintEqualToAnchor(self.contentView.bottomAnchor)
|
||||
self.nameLabelBottomAnchorConstraint.active = true
|
||||
|
||||
self.imageViewWidthConstraint = self.imageView.widthAnchor.constraintEqualToConstant(self.maximumBoxArtSize.width)
|
||||
self.imageViewWidthConstraint.active = true
|
||||
|
||||
self.imageViewHeightConstraint = self.imageView.heightAnchor.constraintEqualToConstant(self.maximumBoxArtSize.height)
|
||||
self.imageViewHeightConstraint.active = true
|
||||
}
|
||||
|
||||
override func applyLayoutAttributes(layoutAttributes: UICollectionViewLayoutAttributes)
|
||||
{
|
||||
guard let attributes = layoutAttributes as? GameCollectionViewLayoutAttributes else { return }
|
||||
|
||||
self.maximumBoxArtSize = attributes.maximumBoxArtSize
|
||||
}
|
||||
|
||||
override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator)
|
||||
{
|
||||
super.didUpdateFocusInContext(context, withAnimationCoordinator: coordinator)
|
||||
|
||||
coordinator.addCoordinatedAnimations({
|
||||
|
||||
if context.nextFocusedView == self
|
||||
{
|
||||
self.nameLabelBottomAnchorConstraint?.active = false
|
||||
self.nameLabelVerticalSpacingConstraint.active = false
|
||||
|
||||
self.nameLabelFocusedVerticalSpacingConstraint?.active = true
|
||||
|
||||
self.nameLabel.textColor = UIColor.whiteColor()
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
self.nameLabelFocusedVerticalSpacingConstraint?.active = false
|
||||
|
||||
self.nameLabelBottomAnchorConstraint?.active = true
|
||||
self.nameLabelVerticalSpacingConstraint.active = true
|
||||
|
||||
self.nameLabel.textColor = UIColor.blackColor()
|
||||
}
|
||||
|
||||
self.layoutIfNeeded()
|
||||
|
||||
}, completion: nil)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
122
Common/Collection View/GameCollectionViewDataSource.swift
Normal file
122
Common/Collection View/GameCollectionViewDataSource.swift
Normal file
@ -0,0 +1,122 @@
|
||||
//
|
||||
// GameCollectionViewDataSource.swift
|
||||
// Delta
|
||||
//
|
||||
// Created by Riley Testut on 10/30/15.
|
||||
// Copyright © 2015 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import CoreData
|
||||
|
||||
class GameCollectionViewDataSource: NSObject
|
||||
{
|
||||
var gameTypeIdentifiers: [String] = [] {
|
||||
didSet
|
||||
{
|
||||
self.updateFetchedResultsController()
|
||||
}
|
||||
}
|
||||
|
||||
var sectionTitles: [String] = []
|
||||
|
||||
var cellConfigurationHandler: ((GameCollectionViewCell, Game) -> Void)?
|
||||
|
||||
private(set) var fetchedResultsController: NSFetchedResultsController = NSFetchedResultsController()
|
||||
private let prototypeCell = GameCollectionViewCell(frame: CGRectZero)
|
||||
|
||||
// MARK: - Update -
|
||||
|
||||
func update()
|
||||
{
|
||||
do
|
||||
{
|
||||
try self.fetchedResultsController.performFetch()
|
||||
}
|
||||
catch let error as NSError
|
||||
{
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateFetchedResultsController()
|
||||
{
|
||||
let previousDelegate = self.fetchedResultsController.delegate
|
||||
|
||||
let fetchRequest = Game.fetchRequest()
|
||||
|
||||
var predicates: [NSPredicate] = []
|
||||
|
||||
for typeIdentifier in self.gameTypeIdentifiers
|
||||
{
|
||||
let predicate = NSPredicate(format: "%K == %@", GameAttributes.typeIdentifier.rawValue, typeIdentifier)
|
||||
predicates.append(predicate)
|
||||
}
|
||||
|
||||
if predicates.count > 0
|
||||
{
|
||||
fetchRequest.predicate = NSCompoundPredicate(orPredicateWithSubpredicates: predicates)
|
||||
}
|
||||
|
||||
fetchRequest.sortDescriptors = [NSSortDescriptor(key: GameAttributes.name.rawValue, ascending: true)]
|
||||
|
||||
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.sharedManager.managedObjectContext, sectionNameKeyPath: GameAttributes.typeIdentifier.rawValue, cacheName: nil)
|
||||
self.fetchedResultsController.delegate = previousDelegate
|
||||
|
||||
self.update()
|
||||
}
|
||||
|
||||
// MARK: - Collection View -
|
||||
|
||||
private func configureCell(cell: GameCollectionViewCell, forIndexPath indexPath: NSIndexPath)
|
||||
{
|
||||
let game = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Game
|
||||
|
||||
if let handler = self.cellConfigurationHandler
|
||||
{
|
||||
handler(cell, game)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension GameCollectionViewDataSource: UICollectionViewDataSource
|
||||
{
|
||||
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int
|
||||
{
|
||||
return self.fetchedResultsController.sections?.count ?? 0
|
||||
}
|
||||
|
||||
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
|
||||
{
|
||||
let count = self.fetchedResultsController.sections?[section].numberOfObjects ?? 0
|
||||
return count
|
||||
}
|
||||
|
||||
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
|
||||
{
|
||||
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("GameCell", forIndexPath: indexPath) as! GameCollectionViewCell
|
||||
|
||||
self.configureCell(cell, forIndexPath: indexPath)
|
||||
|
||||
return cell
|
||||
}
|
||||
}
|
||||
|
||||
extension GameCollectionViewDataSource: UICollectionViewDelegate
|
||||
{
|
||||
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
|
||||
{
|
||||
if let layoutAttributes = collectionViewLayout.layoutAttributesForItemAtIndexPath(indexPath)
|
||||
{
|
||||
self.prototypeCell.applyLayoutAttributes(layoutAttributes)
|
||||
}
|
||||
|
||||
self.configureCell(self.prototypeCell, forIndexPath: indexPath)
|
||||
self.prototypeCell.layoutIfNeeded()
|
||||
|
||||
let size = self.prototypeCell.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
|
||||
return size
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
113
Common/Collection View/GameCollectionViewLayout.swift
Normal file
113
Common/Collection View/GameCollectionViewLayout.swift
Normal file
@ -0,0 +1,113 @@
|
||||
//
|
||||
// GameCollectionViewLayout.swift
|
||||
// Delta
|
||||
//
|
||||
// Created by Riley Testut on 10/24/15.
|
||||
// Copyright © 2015 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class GameCollectionViewLayout: UICollectionViewFlowLayout
|
||||
{
|
||||
var maximumBoxArtSize = CGSize(width: 100, height: 100) {
|
||||
didSet
|
||||
{
|
||||
self.invalidateLayout()
|
||||
}
|
||||
}
|
||||
|
||||
override class func layoutAttributesClass() -> AnyClass
|
||||
{
|
||||
return GameCollectionViewLayoutAttributes.self
|
||||
}
|
||||
|
||||
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes?
|
||||
{
|
||||
// Need to implement this method as well in case the view controller calls it (which it does)
|
||||
|
||||
let layoutAttributes = super.layoutAttributesForItemAtIndexPath(indexPath)?.copy() as! GameCollectionViewLayoutAttributes
|
||||
self.configureLayoutAttributes(layoutAttributes)
|
||||
|
||||
return layoutAttributes
|
||||
}
|
||||
|
||||
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]?
|
||||
{
|
||||
guard let collectionView = self.collectionView else { return nil }
|
||||
|
||||
let maximumItemsPerRow = floor((collectionView.bounds.width - self.minimumInteritemSpacing) / (self.maximumBoxArtSize.width + self.minimumInteritemSpacing))
|
||||
let interitemSpacing = (collectionView.bounds.width - maximumItemsPerRow * self.maximumBoxArtSize.width) / (maximumItemsPerRow + 1)
|
||||
|
||||
self.sectionInset = UIEdgeInsets(top: interitemSpacing, left: interitemSpacing, bottom: interitemSpacing, right: interitemSpacing)
|
||||
|
||||
let layoutAttributes = super.layoutAttributesForElementsInRect(rect)?.map({ $0.copy() }) as! [GameCollectionViewLayoutAttributes]
|
||||
|
||||
var minimumY: CGFloat? = nil
|
||||
var maximumY: CGFloat? = nil
|
||||
var tempLayoutAttributes: [GameCollectionViewLayoutAttributes] = []
|
||||
|
||||
for (index, attributes) in layoutAttributes.enumerate()
|
||||
{
|
||||
// Ensure equal spacing between items (that also match the section insets)
|
||||
if index > 0
|
||||
{
|
||||
let previousLayoutAttributes = layoutAttributes[index - 1]
|
||||
|
||||
if abs(attributes.frame.minX - self.sectionInset.left) > 1
|
||||
{
|
||||
attributes.frame.origin.x = previousLayoutAttributes.frame.maxX + interitemSpacing
|
||||
}
|
||||
}
|
||||
|
||||
self.configureLayoutAttributes(attributes)
|
||||
|
||||
if let maxY = maximumY, minY = minimumY
|
||||
{
|
||||
// If attributes.frame.minY is greater than maximumY, then it is a new row
|
||||
// In this case, we need to align all the previous tempLayoutAttributes to the same Y-value
|
||||
if attributes.frame.minY > maxY
|
||||
{
|
||||
for tempAttributes in tempLayoutAttributes
|
||||
{
|
||||
tempAttributes.frame.origin.y = minY
|
||||
}
|
||||
|
||||
// Reset tempLayoutAttributes
|
||||
tempLayoutAttributes.removeAll()
|
||||
minimumY = nil
|
||||
maximumY = nil
|
||||
}
|
||||
}
|
||||
|
||||
if minimumY == nil || attributes.frame.minY < minimumY!
|
||||
{
|
||||
minimumY = attributes.frame.minY
|
||||
}
|
||||
|
||||
if maximumY == nil || attributes.frame.maxY > maximumY!
|
||||
{
|
||||
maximumY = attributes.frame.maxY
|
||||
}
|
||||
|
||||
tempLayoutAttributes.append(attributes)
|
||||
}
|
||||
|
||||
// Handle the remaining tempLayoutAttributes
|
||||
if let minimumY = minimumY
|
||||
{
|
||||
for tempAttributes in tempLayoutAttributes
|
||||
{
|
||||
tempAttributes.frame.origin.y = minimumY
|
||||
}
|
||||
}
|
||||
|
||||
return layoutAttributes
|
||||
}
|
||||
|
||||
// You'd think you could just do this in layoutAttributesForItemAtIndexPath, but alas layoutAttributesForElementsInRect does not call that method :(
|
||||
private func configureLayoutAttributes(layoutAttributes: GameCollectionViewLayoutAttributes)
|
||||
{
|
||||
layoutAttributes.maximumBoxArtSize = self.maximumBoxArtSize
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
//
|
||||
// GameCollectionViewLayoutAttributes.swift
|
||||
// Delta
|
||||
//
|
||||
// Created by Riley Testut on 10/28/15.
|
||||
// Copyright © 2015 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class GameCollectionViewLayoutAttributes: UICollectionViewLayoutAttributes
|
||||
{
|
||||
var maximumBoxArtSize = CGSize(width: 100, height: 100)
|
||||
|
||||
override func copyWithZone(zone: NSZone) -> AnyObject
|
||||
{
|
||||
let copy = super.copyWithZone(zone) as! GameCollectionViewLayoutAttributes
|
||||
copy.maximumBoxArtSize = self.maximumBoxArtSize
|
||||
|
||||
return copy
|
||||
}
|
||||
|
||||
override func isEqual(object: AnyObject?) -> Bool
|
||||
{
|
||||
guard super.isEqual(object) else { return false }
|
||||
guard let attributes = object as? GameCollectionViewLayoutAttributes else { return false }
|
||||
|
||||
guard CGSizeEqualToSize(self.maximumBoxArtSize, attributes.maximumBoxArtSize) else { return false }
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
55
Common/Components/BoxArtImageView.swift
Normal file
55
Common/Components/BoxArtImageView.swift
Normal file
@ -0,0 +1,55 @@
|
||||
//
|
||||
// BoxArtImageView.swift
|
||||
// Delta
|
||||
//
|
||||
// Created by Riley Testut on 10/27/15.
|
||||
// Copyright © 2015 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class BoxArtImageView: UIImageView
|
||||
{
|
||||
override var image: UIImage? {
|
||||
didSet
|
||||
{
|
||||
if image == nil
|
||||
{
|
||||
image = UIImage(named: "BoxArt")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
init()
|
||||
{
|
||||
super.init(image: nil)
|
||||
|
||||
self.initialize()
|
||||
}
|
||||
|
||||
override init(frame: CGRect)
|
||||
{
|
||||
super.init(frame: frame)
|
||||
|
||||
self.image = nil
|
||||
|
||||
self.initialize()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder)
|
||||
{
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
self.initialize()
|
||||
}
|
||||
|
||||
private func initialize()
|
||||
{
|
||||
#if os(tvOS)
|
||||
self.adjustsImageWhenAncestorFocused = true
|
||||
#endif
|
||||
|
||||
self.contentMode = .ScaleAspectFit
|
||||
}
|
||||
}
|
||||
@ -14,17 +14,22 @@
|
||||
BF27CC8D1BC9FE5300A20D89 /* Pods.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 22506DA00971C4300AF90A35 /* Pods.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
BF27CC8E1BC9FEA200A20D89 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BF6BB2451BB73FE800CCF94A /* Assets.xcassets */; };
|
||||
BF27CC8F1BCA010200A20D89 /* GamePickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDB28441BC9DA7B001D0C83 /* GamePickerController.swift */; };
|
||||
BF27CC911BCB156200A20D89 /* EmulationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF27CC901BCB156200A20D89 /* EmulationViewController.swift */; };
|
||||
BF27CC951BCB7B7A00A20D89 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF27CC941BCB7B7A00A20D89 /* GameController.framework */; };
|
||||
BF27CC971BCC890700A20D89 /* GamesCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF27CC961BCC890700A20D89 /* GamesCollectionViewController.swift */; };
|
||||
BF27CC991BCC8AE600A20D89 /* GamesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF27CC981BCC8AE600A20D89 /* GamesViewController.swift */; };
|
||||
BF2A53FB1BB74FC10052BD0C /* SNESDeltaCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFC134E01AAD82460087AD7B /* SNESDeltaCore.framework */; };
|
||||
BF2A53FC1BB74FC10052BD0C /* SNESDeltaCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BFC134E01AAD82460087AD7B /* SNESDeltaCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
BF2A53FD1BB74FC60052BD0C /* ZipZap.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF70798B1B6B464B0019077C /* ZipZap.framework */; };
|
||||
BF2A53FE1BB74FC60052BD0C /* ZipZap.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BF70798B1B6B464B0019077C /* ZipZap.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
BF4566E81BC090B6007BFA1A /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = BF4566E61BC090B6007BFA1A /* Model.xcdatamodeld */; };
|
||||
BF4566E91BC090B6007BFA1A /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = BF4566E61BC090B6007BFA1A /* Model.xcdatamodeld */; };
|
||||
BF46894F1AAC46EF00A2586D /* DirectoryContentsDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF46894E1AAC46EF00A2586D /* DirectoryContentsDataSource.swift */; };
|
||||
BF50DC421BD851740024C720 /* GameCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF50DC411BD851740024C720 /* GameCollectionViewCell.swift */; };
|
||||
BF50DC431BD851740024C720 /* GameCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF50DC411BD851740024C720 /* GameCollectionViewCell.swift */; };
|
||||
BF5E7F441B9A650B00AE44F8 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5E7F431B9A650B00AE44F8 /* SettingsViewController.swift */; };
|
||||
BF5E7F461B9A652600AE44F8 /* Settings.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BF5E7F451B9A652600AE44F8 /* Settings.storyboard */; };
|
||||
BF6BB23F1BB73FE800CCF94A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6BB23E1BB73FE800CCF94A /* AppDelegate.swift */; };
|
||||
BF6BB2411BB73FE800CCF94A /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6BB2401BB73FE800CCF94A /* ViewController.swift */; };
|
||||
BF6BB2411BB73FE800CCF94A /* GameSelectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6BB2401BB73FE800CCF94A /* GameSelectionViewController.swift */; };
|
||||
BF6BB2441BB73FE800CCF94A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BF6BB2421BB73FE800CCF94A /* Main.storyboard */; };
|
||||
BF6BB2461BB73FE800CCF94A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BF6BB2451BB73FE800CCF94A /* Assets.xcassets */; };
|
||||
BF70798C1B6B464B0019077C /* ZipZap.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF70798B1B6B464B0019077C /* ZipZap.framework */; };
|
||||
@ -39,8 +44,12 @@
|
||||
BF8624AA1BB7464B00C12EEE /* DeltaCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BF9F4FCE1AAD7B87004C9500 /* DeltaCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
BF9F4FCF1AAD7B87004C9500 /* DeltaCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF9F4FCE1AAD7B87004C9500 /* DeltaCore.framework */; };
|
||||
BF9F4FD01AAD7B87004C9500 /* DeltaCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BF9F4FCE1AAD7B87004C9500 /* DeltaCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
BFA5342A1BDC6B520088F1BE /* GameCollectionViewLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA534291BDC6B520088F1BE /* GameCollectionViewLayout.swift */; };
|
||||
BFA5342B1BDC6B520088F1BE /* GameCollectionViewLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA534291BDC6B520088F1BE /* GameCollectionViewLayout.swift */; };
|
||||
BFAA1FED1B8AA4FA00495943 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFAA1FEC1B8AA4FA00495943 /* Settings.swift */; };
|
||||
BFAA1FF41B8AD7F900495943 /* ControllersSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFAA1FF31B8AD7F900495943 /* ControllersSettingsViewController.swift */; };
|
||||
BFB141181BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB141171BE46934004FBF46 /* GameCollectionViewDataSource.swift */; };
|
||||
BFB141191BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB141171BE46934004FBF46 /* GameCollectionViewDataSource.swift */; };
|
||||
BFC134E11AAD82460087AD7B /* SNESDeltaCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFC134E01AAD82460087AD7B /* SNESDeltaCore.framework */; };
|
||||
BFC134E21AAD82470087AD7B /* SNESDeltaCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BFC134E01AAD82460087AD7B /* SNESDeltaCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
BFDB28451BC9DA7B001D0C83 /* GamePickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDB28441BC9DA7B001D0C83 /* GamePickerController.swift */; };
|
||||
@ -50,12 +59,14 @@
|
||||
BFDE393D1BC0CEDF003F72E8 /* Game.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDE39391BC0CEDF003F72E8 /* Game.swift */; };
|
||||
BFEC732D1AAECC4A00650035 /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFEC732C1AAECC4A00650035 /* Roxas.framework */; };
|
||||
BFEC732E1AAECC4A00650035 /* Roxas.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BFEC732C1AAECC4A00650035 /* Roxas.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
BFF1E5641BE04CAF000E9EF6 /* BoxArtImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF1E5631BE04CAF000E9EF6 /* BoxArtImageView.swift */; };
|
||||
BFF1E5651BE04CAF000E9EF6 /* BoxArtImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF1E5631BE04CAF000E9EF6 /* BoxArtImageView.swift */; };
|
||||
BFF4EA011BE1B2420056AAA4 /* GameCollectionViewLayoutAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF4EA001BE1B2420056AAA4 /* GameCollectionViewLayoutAttributes.swift */; };
|
||||
BFF4EA021BE1B2420056AAA4 /* GameCollectionViewLayoutAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF4EA001BE1B2420056AAA4 /* GameCollectionViewLayoutAttributes.swift */; };
|
||||
BFFA71DD1AAC406100EE9DD1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFA71DC1AAC406100EE9DD1 /* AppDelegate.swift */; };
|
||||
BFFA71DF1AAC406100EE9DD1 /* GamesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFA71DE1AAC406100EE9DD1 /* GamesViewController.swift */; };
|
||||
BFFA71E21AAC406100EE9DD1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BFFA71E01AAC406100EE9DD1 /* Main.storyboard */; };
|
||||
BFFA71E71AAC406100EE9DD1 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = BFFA71E51AAC406100EE9DD1 /* LaunchScreen.xib */; };
|
||||
BFFB709F1AF99B1700DE56FE /* EmulationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFB709E1AF99B1700DE56FE /* EmulationViewController.swift */; };
|
||||
BFFB70A11AF99DFB00DE56FE /* EmulationViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BFFB70A01AF99DFB00DE56FE /* EmulationViewController.xib */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@ -99,13 +110,17 @@
|
||||
BF090CF31B490D8300DCAB45 /* UIDevice+Vibration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIDevice+Vibration.m"; sourceTree = "<group>"; };
|
||||
BF27CC861BC9E3C600A20D89 /* Delta.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Delta.entitlements; sourceTree = "<group>"; };
|
||||
BF27CC8A1BC9FE4D00A20D89 /* Pods.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Pods.framework; path = "Pods/../build/Debug-appletvos/Pods.framework"; sourceTree = "<group>"; };
|
||||
BF27CC901BCB156200A20D89 /* EmulationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmulationViewController.swift; sourceTree = "<group>"; };
|
||||
BF27CC941BCB7B7A00A20D89 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS9.0.sdk/System/Library/Frameworks/GameController.framework; sourceTree = DEVELOPER_DIR; };
|
||||
BF27CC961BCC890700A20D89 /* GamesCollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GamesCollectionViewController.swift; sourceTree = "<group>"; };
|
||||
BF27CC981BCC8AE600A20D89 /* GamesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GamesViewController.swift; sourceTree = "<group>"; };
|
||||
BF4566E71BC090B6007BFA1A /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = "<group>"; };
|
||||
BF46894E1AAC46EF00A2586D /* DirectoryContentsDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DirectoryContentsDataSource.swift; sourceTree = "<group>"; };
|
||||
BF50DC411BD851740024C720 /* GameCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameCollectionViewCell.swift; path = "Collection View/GameCollectionViewCell.swift"; sourceTree = "<group>"; };
|
||||
BF5E7F431B9A650B00AE44F8 /* SettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = "<group>"; };
|
||||
BF5E7F451B9A652600AE44F8 /* Settings.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Settings.storyboard; sourceTree = "<group>"; };
|
||||
BF6BB23C1BB73FE800CCF94A /* Delta.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Delta.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
BF6BB23E1BB73FE800CCF94A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
BF6BB2401BB73FE800CCF94A /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
||||
BF6BB2401BB73FE800CCF94A /* GameSelectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameSelectionViewController.swift; sourceTree = "<group>"; };
|
||||
BF6BB2431BB73FE800CCF94A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
BF6BB2451BB73FE800CCF94A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
BF6BB2471BB73FE800CCF94A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
@ -113,21 +128,23 @@
|
||||
BF762E9D1BC19D31002C8866 /* DatabaseManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DatabaseManager.swift; sourceTree = "<group>"; };
|
||||
BF762EAA1BC1B076002C8866 /* NSManagedObject+Conveniences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Conveniences.swift"; sourceTree = "<group>"; };
|
||||
BF9F4FCE1AAD7B87004C9500 /* DeltaCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DeltaCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
BFA534291BDC6B520088F1BE /* GameCollectionViewLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameCollectionViewLayout.swift; path = "Collection View/GameCollectionViewLayout.swift"; sourceTree = "<group>"; };
|
||||
BFAA1FEC1B8AA4FA00495943 /* Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = "<group>"; };
|
||||
BFAA1FF31B8AD7F900495943 /* ControllersSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControllersSettingsViewController.swift; sourceTree = "<group>"; };
|
||||
BFB141171BE46934004FBF46 /* GameCollectionViewDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameCollectionViewDataSource.swift; path = "Collection View/GameCollectionViewDataSource.swift"; sourceTree = "<group>"; };
|
||||
BFC134E01AAD82460087AD7B /* SNESDeltaCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SNESDeltaCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
BFDB28441BC9DA7B001D0C83 /* GamePickerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GamePickerController.swift; sourceTree = "<group>"; };
|
||||
BFDE39381BC0CEDF003F72E8 /* Game+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Game+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||
BFDE39391BC0CEDF003F72E8 /* Game.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Game.swift; sourceTree = "<group>"; };
|
||||
BFEC732C1AAECC4A00650035 /* Roxas.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Roxas.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
BFF1E5631BE04CAF000E9EF6 /* BoxArtImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BoxArtImageView.swift; path = Components/BoxArtImageView.swift; sourceTree = "<group>"; };
|
||||
BFF4EA001BE1B2420056AAA4 /* GameCollectionViewLayoutAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameCollectionViewLayoutAttributes.swift; path = "Collection View/GameCollectionViewLayoutAttributes.swift"; sourceTree = "<group>"; };
|
||||
BFFA71D71AAC406100EE9DD1 /* Delta.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Delta.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
BFFA71DB1AAC406100EE9DD1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
BFFA71DC1AAC406100EE9DD1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
BFFA71DE1AAC406100EE9DD1 /* GamesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GamesViewController.swift; sourceTree = "<group>"; };
|
||||
BFFA71E11AAC406100EE9DD1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
BFFA71E61AAC406100EE9DD1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
BFFB709E1AF99B1700DE56FE /* EmulationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmulationViewController.swift; sourceTree = "<group>"; };
|
||||
BFFB70A01AF99DFB00DE56FE /* EmulationViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = EmulationViewController.xib; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -137,6 +154,7 @@
|
||||
files = (
|
||||
BF2A53FB1BB74FC10052BD0C /* SNESDeltaCore.framework in Frameworks */,
|
||||
BF8624A91BB7464B00C12EEE /* DeltaCore.framework in Frameworks */,
|
||||
BF27CC951BCB7B7A00A20D89 /* GameController.framework in Frameworks */,
|
||||
BF2A53FD1BB74FC60052BD0C /* ZipZap.framework in Frameworks */,
|
||||
BF8624881BB743FE00C12EEE /* Roxas.framework in Frameworks */,
|
||||
AF0535CD7331785FA15E0864 /* Pods.framework in Frameworks */,
|
||||
@ -180,6 +198,8 @@
|
||||
BF4566E31BC09026007BFA1A /* Common */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BFF1E55F1BE04BF6000E9EF6 /* Components */,
|
||||
BF9257571BD8244800B109DA /* Collection View */,
|
||||
BF4566E41BC0902E007BFA1A /* Database */,
|
||||
BFDB28431BC9D9D1001D0C83 /* Importing */,
|
||||
BF762EA91BC1B044002C8866 /* Extensions */,
|
||||
@ -209,8 +229,8 @@
|
||||
BF46894D1AAC469800A2586D /* Game Selection */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF46894E1AAC46EF00A2586D /* DirectoryContentsDataSource.swift */,
|
||||
BFFA71DE1AAC406100EE9DD1 /* GamesViewController.swift */,
|
||||
BF27CC981BCC8AE600A20D89 /* GamesViewController.swift */,
|
||||
BF27CC961BCC890700A20D89 /* GamesCollectionViewController.swift */,
|
||||
);
|
||||
path = "Game Selection";
|
||||
sourceTree = "<group>";
|
||||
@ -220,7 +240,8 @@
|
||||
children = (
|
||||
BF6BB23E1BB73FE800CCF94A /* AppDelegate.swift */,
|
||||
BF6BB2421BB73FE800CCF94A /* Main.storyboard */,
|
||||
BF6BB2401BB73FE800CCF94A /* ViewController.swift */,
|
||||
BF6BB2401BB73FE800CCF94A /* GameSelectionViewController.swift */,
|
||||
BF27CC901BCB156200A20D89 /* EmulationViewController.swift */,
|
||||
BF8624621BB7400E00C12EEE /* Supporting Files */,
|
||||
);
|
||||
path = DeltaTV;
|
||||
@ -242,9 +263,21 @@
|
||||
path = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BF9257571BD8244800B109DA /* Collection View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF50DC411BD851740024C720 /* GameCollectionViewCell.swift */,
|
||||
BFA534291BDC6B520088F1BE /* GameCollectionViewLayout.swift */,
|
||||
BFF4EA001BE1B2420056AAA4 /* GameCollectionViewLayoutAttributes.swift */,
|
||||
BFB141171BE46934004FBF46 /* GameCollectionViewDataSource.swift */,
|
||||
);
|
||||
name = "Collection View";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BF9F4FCD1AAD7B25004C9500 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF27CC941BCB7B7A00A20D89 /* GameController.framework */,
|
||||
BF27CC8A1BC9FE4D00A20D89 /* Pods.framework */,
|
||||
BF70798B1B6B464B0019077C /* ZipZap.framework */,
|
||||
BFEC732C1AAECC4A00650035 /* Roxas.framework */,
|
||||
@ -282,6 +315,14 @@
|
||||
path = Resources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BFF1E55F1BE04BF6000E9EF6 /* Components */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BFF1E5631BE04CAF000E9EF6 /* BoxArtImageView.swift */,
|
||||
);
|
||||
name = Components;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BFFA71CE1AAC406100EE9DD1 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -333,7 +374,6 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BFFB709E1AF99B1700DE56FE /* EmulationViewController.swift */,
|
||||
BFFB70A01AF99DFB00DE56FE /* EmulationViewController.xib */,
|
||||
);
|
||||
path = Emulation;
|
||||
sourceTree = "<group>";
|
||||
@ -396,6 +436,11 @@
|
||||
BF6BB23B1BB73FE800CCF94A = {
|
||||
CreatedOnToolsVersion = 7.1;
|
||||
DevelopmentTeam = 6XVY5G3U44;
|
||||
SystemCapabilities = {
|
||||
com.apple.GameControllers.appletvos = {
|
||||
enabled = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
BFFA71D61AAC406100EE9DD1 = {
|
||||
CreatedOnToolsVersion = 6.3;
|
||||
@ -442,7 +487,6 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
BFFA71E21AAC406100EE9DD1 /* Main.storyboard in Resources */,
|
||||
BFFB70A11AF99DFB00DE56FE /* EmulationViewController.xib in Resources */,
|
||||
BFFA71E71AAC406100EE9DD1 /* LaunchScreen.xib in Resources */,
|
||||
BF5E7F461B9A652600AE44F8 /* Settings.storyboard in Resources */,
|
||||
BF27CC8E1BC9FEA200A20D89 /* Assets.xcassets in Resources */,
|
||||
@ -549,11 +593,17 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
BF6BB2411BB73FE800CCF94A /* ViewController.swift in Sources */,
|
||||
BFF4EA021BE1B2420056AAA4 /* GameCollectionViewLayoutAttributes.swift in Sources */,
|
||||
BF6BB2411BB73FE800CCF94A /* GameSelectionViewController.swift in Sources */,
|
||||
BF27CC8F1BCA010200A20D89 /* GamePickerController.swift in Sources */,
|
||||
BFDE393D1BC0CEDF003F72E8 /* Game.swift in Sources */,
|
||||
BF762E9F1BC19D31002C8866 /* DatabaseManager.swift in Sources */,
|
||||
BFDE393B1BC0CEDF003F72E8 /* Game+CoreDataProperties.swift in Sources */,
|
||||
BF27CC911BCB156200A20D89 /* EmulationViewController.swift in Sources */,
|
||||
BFB141191BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */,
|
||||
BFF1E5651BE04CAF000E9EF6 /* BoxArtImageView.swift in Sources */,
|
||||
BF50DC431BD851740024C720 /* GameCollectionViewCell.swift in Sources */,
|
||||
BFA5342B1BDC6B520088F1BE /* GameCollectionViewLayout.swift in Sources */,
|
||||
BF6BB23F1BB73FE800CCF94A /* AppDelegate.swift in Sources */,
|
||||
BF4566E91BC090B6007BFA1A /* Model.xcdatamodeld in Sources */,
|
||||
BF762EAC1BC1B076002C8866 /* NSManagedObject+Conveniences.swift in Sources */,
|
||||
@ -564,15 +614,20 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
BF27CC991BCC8AE600A20D89 /* GamesViewController.swift in Sources */,
|
||||
BFF4EA011BE1B2420056AAA4 /* GameCollectionViewLayoutAttributes.swift in Sources */,
|
||||
BFAA1FED1B8AA4FA00495943 /* Settings.swift in Sources */,
|
||||
BFFA71DF1AAC406100EE9DD1 /* GamesViewController.swift in Sources */,
|
||||
BF50DC421BD851740024C720 /* GameCollectionViewCell.swift in Sources */,
|
||||
BFB141181BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */,
|
||||
BFFB709F1AF99B1700DE56FE /* EmulationViewController.swift in Sources */,
|
||||
BFAA1FF41B8AD7F900495943 /* ControllersSettingsViewController.swift in Sources */,
|
||||
BF27CC971BCC890700A20D89 /* GamesCollectionViewController.swift in Sources */,
|
||||
BFFA71DD1AAC406100EE9DD1 /* AppDelegate.swift in Sources */,
|
||||
BF4566E81BC090B6007BFA1A /* Model.xcdatamodeld in Sources */,
|
||||
BFDE393C1BC0CEDF003F72E8 /* Game.swift in Sources */,
|
||||
BF46894F1AAC46EF00A2586D /* DirectoryContentsDataSource.swift in Sources */,
|
||||
BFF1E5641BE04CAF000E9EF6 /* BoxArtImageView.swift in Sources */,
|
||||
BF762EAB1BC1B076002C8866 /* NSManagedObject+Conveniences.swift in Sources */,
|
||||
BFA5342A1BDC6B520088F1BE /* GameCollectionViewLayout.swift in Sources */,
|
||||
BF762E9E1BC19D31002C8866 /* DatabaseManager.swift in Sources */,
|
||||
BF090CF41B490D8300DCAB45 /* UIDevice+Vibration.m in Sources */,
|
||||
BF5E7F441B9A650B00AE44F8 /* SettingsViewController.swift in Sources */,
|
||||
@ -638,7 +693,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Distribution";
|
||||
INFOPLIST_FILE = "DeltaTV/Supporting Files/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PROVISIONING_PROFILE = "";
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9052" systemVersion="15A284" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="Sqc-e3-Var">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9059" systemVersion="15A284" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="wKV-3d-NIY">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9040"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9049"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Navigation Controller-->
|
||||
@ -66,6 +66,166 @@
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1054" y="333"/>
|
||||
</scene>
|
||||
<!--Games-->
|
||||
<scene sceneID="Cd2-Pf-cua">
|
||||
<objects>
|
||||
<viewController id="jeE-WD-wXO" customClass="GamesViewController" customModule="Delta" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="WoX-O4-qy5"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="0om-QB-N5a"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="3Bk-k3-7J9">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<containerView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tmn-gd-5UN">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<animations/>
|
||||
<connections>
|
||||
<segue destination="tpK-ou-yEA" kind="embed" id="cjU-nW-cHY"/>
|
||||
</connections>
|
||||
</containerView>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="tmn-gd-5UN" secondAttribute="trailing" id="9Rq-HM-vqk"/>
|
||||
<constraint firstItem="0om-QB-N5a" firstAttribute="top" secondItem="tmn-gd-5UN" secondAttribute="bottom" id="DV5-hh-1VN"/>
|
||||
<constraint firstItem="tmn-gd-5UN" firstAttribute="leading" secondItem="3Bk-k3-7J9" secondAttribute="leading" id="f1f-sa-dBA"/>
|
||||
<constraint firstItem="tmn-gd-5UN" firstAttribute="top" secondItem="3Bk-k3-7J9" secondAttribute="top" id="nhS-aC-rUR"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" title="Games" id="pFk-as-3k4">
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="add" id="FeA-O5-xd2">
|
||||
<connections>
|
||||
<action selector="importFiles" destination="jeE-WD-wXO" id="A1s-kE-NkM"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="JYx-xE-nis" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1054" y="1002"/>
|
||||
</scene>
|
||||
<!--Games Collection View Controller-->
|
||||
<scene sceneID="qNA-NP-TiF">
|
||||
<objects>
|
||||
<collectionViewController storyboardIdentifier="gamesCollectionViewController" clearsSelectionOnViewWillAppear="NO" id="kqu-75-owz" customClass="GamesCollectionViewController" customModule="Delta" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" id="OIq-Z8-kxO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="NKN-dd-bTh" customClass="GameCollectionViewLayout" customModule="Delta" customModuleProvider="target">
|
||||
<size key="itemSize" width="100" height="100"/>
|
||||
<size key="headerReferenceSize" width="0.0" height="0.0"/>
|
||||
<size key="footerReferenceSize" width="0.0" height="0.0"/>
|
||||
<inset key="sectionInset" minX="10" minY="10" maxX="10" maxY="10"/>
|
||||
</collectionViewFlowLayout>
|
||||
<cells>
|
||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="GameCell" id="ioT-sh-j8y" customClass="GameCollectionViewCell" customModule="Delta" customModuleProvider="target">
|
||||
<rect key="frame" x="10" y="10" width="100" height="100"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
||||
<rect key="frame" x="0.0" y="0.0" width="100" height="100"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<animations/>
|
||||
<connections>
|
||||
<segue destination="hx4-Ze-0Jw" kind="presentation" id="flc-7j-hej"/>
|
||||
</connections>
|
||||
</collectionViewCell>
|
||||
</cells>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="kqu-75-owz" id="lrW-kx-elN"/>
|
||||
<outlet property="delegate" destination="kqu-75-owz" id="B0G-y1-UrU"/>
|
||||
</connections>
|
||||
</collectionView>
|
||||
</collectionViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="bW1-t8-idm" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1707" y="1002"/>
|
||||
</scene>
|
||||
<!--Emulation View Controller-->
|
||||
<scene sceneID="g58-A4-ib1">
|
||||
<objects>
|
||||
<viewController id="hx4-Ze-0Jw" customClass="EmulationViewController" customModule="Delta" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="Fo4-YI-5cN"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="UIe-oC-tUc"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="7ei-Ah-JvQ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="GfI-Mx-CQT" customClass="GameView" customModule="DeltaCore">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="300"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" placeholderIntrinsicWidth="600" placeholderIntrinsicHeight="300" translatesAutoresizingMaskIntoConstraints="NO" id="2W1-IT-Y2l" customClass="ControllerView" customModule="DeltaCore">
|
||||
<rect key="frame" x="0.0" y="300" width="600" height="300"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="300" id="PEV-zv-Buo"/>
|
||||
</constraints>
|
||||
<variation key="heightClass=compact">
|
||||
<mask key="constraints">
|
||||
<exclude reference="PEV-zv-Buo"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="2W1-IT-Y2l" firstAttribute="top" secondItem="7ei-Ah-JvQ" secondAttribute="top" id="EF1-5h-FJs"/>
|
||||
<constraint firstAttribute="trailing" secondItem="GfI-Mx-CQT" secondAttribute="trailing" id="EKN-e9-x37"/>
|
||||
<constraint firstItem="GfI-Mx-CQT" firstAttribute="top" secondItem="7ei-Ah-JvQ" secondAttribute="top" id="ala-4P-wQR"/>
|
||||
<constraint firstAttribute="bottom" secondItem="GfI-Mx-CQT" secondAttribute="bottom" id="gFo-XU-4PO">
|
||||
<variation key="heightClass=compact" constant="0.0"/>
|
||||
</constraint>
|
||||
<constraint firstItem="GfI-Mx-CQT" firstAttribute="leading" secondItem="7ei-Ah-JvQ" secondAttribute="leading" id="hck-DY-vlt"/>
|
||||
<constraint firstItem="2W1-IT-Y2l" firstAttribute="top" secondItem="GfI-Mx-CQT" secondAttribute="bottom" id="uWb-Cv-NM1"/>
|
||||
<constraint firstAttribute="bottom" secondItem="2W1-IT-Y2l" secondAttribute="bottom" id="vZg-yU-Kqm"/>
|
||||
<constraint firstAttribute="trailing" secondItem="2W1-IT-Y2l" secondAttribute="trailing" id="wcY-Qm-RRC"/>
|
||||
<constraint firstItem="2W1-IT-Y2l" firstAttribute="leading" secondItem="7ei-Ah-JvQ" secondAttribute="leading" id="ygW-0T-DPh"/>
|
||||
</constraints>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="gFo-XU-4PO"/>
|
||||
<exclude reference="EF1-5h-FJs"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=compact">
|
||||
<mask key="constraints">
|
||||
<include reference="gFo-XU-4PO"/>
|
||||
<include reference="EF1-5h-FJs"/>
|
||||
<exclude reference="uWb-Cv-NM1"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="controllerView" destination="2W1-IT-Y2l" id="WCa-LM-fXF"/>
|
||||
<outlet property="controllerViewHeightConstraint" destination="PEV-zv-Buo" id="1jo-Kg-HpO"/>
|
||||
<outlet property="gameView" destination="GfI-Mx-CQT" id="HmP-OA-mci"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="ZYd-It-2t0" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2361" y="1002"/>
|
||||
</scene>
|
||||
<!--Page View Controller-->
|
||||
<scene sceneID="35q-Io-64T">
|
||||
<objects>
|
||||
<pageViewController autoresizesArchivedViewToFullSize="NO" transitionStyle="scroll" navigationOrientation="horizontal" spineLocation="none" id="tpK-ou-yEA" sceneMemberID="viewController"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="TZS-QE-4Yg" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1054" y="1681"/>
|
||||
</scene>
|
||||
<!--Settings-->
|
||||
<scene sceneID="L3X-MM-hJL">
|
||||
<objects>
|
||||
@ -74,6 +234,25 @@
|
||||
</objects>
|
||||
<point key="canvasLocation" x="795.5" y="-88"/>
|
||||
</scene>
|
||||
<!--Navigation Controller-->
|
||||
<scene sceneID="zJI-sC-1sm">
|
||||
<objects>
|
||||
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="wKV-3d-NIY" sceneMemberID="viewController">
|
||||
<toolbarItems/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="wj9-1e-eev">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<animations/>
|
||||
</navigationBar>
|
||||
<nil name="viewControllers"/>
|
||||
<connections>
|
||||
<segue destination="jeE-WD-wXO" kind="relationship" relationship="rootViewController" id="JbW-Xm-9mu"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="0Br-8t-jcG" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="400" y="1002"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="Settings_Button" width="22" height="22"/>
|
||||
|
||||
@ -9,13 +9,19 @@
|
||||
import UIKit
|
||||
|
||||
import DeltaCore
|
||||
import SNESDeltaCore
|
||||
|
||||
class EmulationViewController: UIViewController
|
||||
{
|
||||
//MARK: - Properties -
|
||||
/** Properties **/
|
||||
let game: Game
|
||||
let emulatorCore: EmulatorCore
|
||||
var game: Game! {
|
||||
didSet
|
||||
{
|
||||
self.emulatorCore = SNESEmulatorCore(game: game)
|
||||
}
|
||||
}
|
||||
private(set) var emulatorCore: EmulatorCore!
|
||||
|
||||
//MARK: - Private Properties
|
||||
@IBOutlet private var controllerView: ControllerView!
|
||||
@ -25,21 +31,14 @@ class EmulationViewController: UIViewController
|
||||
|
||||
//MARK: - Initializers -
|
||||
/** Initializers **/
|
||||
required init(game: Game)
|
||||
required init?(coder aDecoder: NSCoder)
|
||||
{
|
||||
self.game = game
|
||||
self.emulatorCore = EmulatorCore(game: game)
|
||||
|
||||
super.init(nibName: "EmulationViewController", bundle: nil)
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("updateControllers"), name: ExternalControllerDidConnectNotification, object: nil)
|
||||
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("updateControllers"), name: ExternalControllerDidDisconnectNotification, object: nil)
|
||||
}
|
||||
|
||||
required init(coder aDecoder: NSCoder) {
|
||||
fatalError("initWithCoder: not implemented.")
|
||||
}
|
||||
|
||||
//MARK: - Overrides
|
||||
/** Overrides **/
|
||||
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9046" systemVersion="14F27" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9046"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="EmulationViewController" customModule="Delta" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="controllerView" destination="vwI-ri-b2R" id="ntJ-HT-evx"/>
|
||||
<outlet property="controllerViewHeightConstraint" destination="6qz-Ae-arR" id="H8i-pm-31E"/>
|
||||
<outlet property="gameView" destination="CgB-i0-wOA" id="WEE-aY-RJo"/>
|
||||
<outlet property="view" destination="iN0-l3-epB" id="eD5-dV-r00"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="CgB-i0-wOA" customClass="GameView" customModule="DeltaCore">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="300"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" placeholderIntrinsicWidth="600" placeholderIntrinsicHeight="300" translatesAutoresizingMaskIntoConstraints="NO" id="vwI-ri-b2R" customClass="ControllerView" customModule="DeltaCore">
|
||||
<rect key="frame" x="0.0" y="300" width="600" height="300"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="300" id="6qz-Ae-arR"/>
|
||||
</constraints>
|
||||
<variation key="heightClass=compact">
|
||||
<mask key="constraints">
|
||||
<exclude reference="6qz-Ae-arR"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="CgB-i0-wOA" secondAttribute="bottom" id="55v-Ds-7WA">
|
||||
<variation key="heightClass=compact" constant="0.0"/>
|
||||
</constraint>
|
||||
<constraint firstItem="CgB-i0-wOA" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="961-Az-XO4"/>
|
||||
<constraint firstAttribute="bottom" secondItem="vwI-ri-b2R" secondAttribute="bottom" id="Blz-Nt-ex2"/>
|
||||
<constraint firstItem="CgB-i0-wOA" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="DyU-Bl-GaA"/>
|
||||
<constraint firstItem="vwI-ri-b2R" firstAttribute="top" secondItem="CgB-i0-wOA" secondAttribute="bottom" id="IYC-AX-EDR"/>
|
||||
<constraint firstAttribute="trailing" secondItem="CgB-i0-wOA" secondAttribute="trailing" id="JcG-hO-3pf"/>
|
||||
<constraint firstAttribute="trailing" secondItem="vwI-ri-b2R" secondAttribute="trailing" id="YbQ-Se-7bk"/>
|
||||
<constraint firstItem="vwI-ri-b2R" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="ZYq-E4-bHb"/>
|
||||
<constraint firstItem="vwI-ri-b2R" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="mX7-Cl-eSm"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="55v-Ds-7WA"/>
|
||||
<exclude reference="ZYq-E4-bHb"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=compact">
|
||||
<mask key="constraints">
|
||||
<include reference="55v-Ds-7WA"/>
|
||||
<exclude reference="IYC-AX-EDR"/>
|
||||
<include reference="ZYq-E4-bHb"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
@ -1,118 +0,0 @@
|
||||
//
|
||||
// DirectoryContentsDataSource.swift
|
||||
// Delta
|
||||
//
|
||||
// Created by Riley Testut on 3/8/15.
|
||||
// Copyright (c) 2015 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Foundation
|
||||
|
||||
public extension DirectoryContentsDataSource
|
||||
{
|
||||
func URLAtIndexPath(indexPath: NSIndexPath) -> NSURL
|
||||
{
|
||||
let URL = self.directoryContents[indexPath.row]
|
||||
return URL
|
||||
}
|
||||
}
|
||||
|
||||
public class DirectoryContentsDataSource: NSObject
|
||||
{
|
||||
public let directoryURL: NSURL
|
||||
public var tableViewCellIdentifier: String = "Cell"
|
||||
|
||||
public var contentsUpdateHandler: (Void -> Void)?
|
||||
public var cellConfigurationBlock: ((UITableViewCell, NSIndexPath, NSURL) -> Void)?
|
||||
|
||||
private let fileDescriptor: Int32
|
||||
private let directoryMonitorDispatchQueue: dispatch_queue_t
|
||||
private let directoryMonitorDispatchSource: dispatch_source_t!
|
||||
|
||||
private var directoryContents: [NSURL]
|
||||
|
||||
required public init?(directoryURL: NSURL)
|
||||
{
|
||||
self.directoryURL = directoryURL
|
||||
self.fileDescriptor = open(self.directoryURL.fileSystemRepresentation, O_EVTONLY)
|
||||
|
||||
self.directoryMonitorDispatchQueue = dispatch_queue_create("com.rileytestut.DirectoryContentsDataSource", DISPATCH_QUEUE_SERIAL)
|
||||
self.directoryMonitorDispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, UInt(self.fileDescriptor), DISPATCH_VNODE_WRITE, self.directoryMonitorDispatchQueue)
|
||||
|
||||
self.directoryContents = [NSURL]()
|
||||
|
||||
super.init()
|
||||
|
||||
if self.fileDescriptor < 0
|
||||
{
|
||||
return nil
|
||||
}
|
||||
|
||||
if self.directoryMonitorDispatchSource == nil
|
||||
{
|
||||
close(self.fileDescriptor);
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
dispatch_source_set_event_handler(self.directoryMonitorDispatchSource, {
|
||||
self.didUpdateDirectoryContents()
|
||||
});
|
||||
|
||||
dispatch_source_set_cancel_handler(self.directoryMonitorDispatchSource, {
|
||||
close(self.fileDescriptor);
|
||||
});
|
||||
|
||||
dispatch_resume(self.directoryMonitorDispatchSource);
|
||||
|
||||
self.didUpdateDirectoryContents()
|
||||
}
|
||||
|
||||
deinit
|
||||
{
|
||||
if self.fileDescriptor >= 0
|
||||
{
|
||||
close(self.fileDescriptor);
|
||||
}
|
||||
|
||||
if self.directoryMonitorDispatchSource != nil
|
||||
{
|
||||
dispatch_source_cancel(self.directoryMonitorDispatchSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension DirectoryContentsDataSource
|
||||
{
|
||||
func didUpdateDirectoryContents()
|
||||
{
|
||||
do
|
||||
{
|
||||
self.directoryContents = try NSFileManager.defaultManager().contentsOfDirectoryAtURL(self.directoryURL, includingPropertiesForKeys: nil, options:[NSDirectoryEnumerationOptions.SkipsSubdirectoryDescendants, NSDirectoryEnumerationOptions.SkipsHiddenFiles])
|
||||
}
|
||||
catch let error as NSError
|
||||
{
|
||||
print("\(error) \(error.userInfo)")
|
||||
}
|
||||
|
||||
self.contentsUpdateHandler?()
|
||||
}
|
||||
}
|
||||
|
||||
extension DirectoryContentsDataSource: UITableViewDataSource
|
||||
{
|
||||
public func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
|
||||
{
|
||||
return self.directoryContents.count
|
||||
}
|
||||
|
||||
public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
|
||||
{
|
||||
let tableViewCell = tableView.dequeueReusableCellWithIdentifier(self.tableViewCellIdentifier, forIndexPath: indexPath) as UITableViewCell
|
||||
|
||||
self.cellConfigurationBlock?(tableViewCell, indexPath, self.URLAtIndexPath(indexPath))
|
||||
|
||||
return tableViewCell
|
||||
}
|
||||
}
|
||||
86
Delta/Game Selection/GamesCollectionViewController.swift
Normal file
86
Delta/Game Selection/GamesCollectionViewController.swift
Normal file
@ -0,0 +1,86 @@
|
||||
//
|
||||
// GamesCollectionViewController.swift
|
||||
// Delta
|
||||
//
|
||||
// Created by Riley Testut on 10/12/15.
|
||||
// Copyright © 2015 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import CoreData
|
||||
|
||||
import DeltaCore
|
||||
|
||||
class GamesCollectionViewController: UICollectionViewController
|
||||
{
|
||||
var gameTypeIdentifier: String! {
|
||||
didSet
|
||||
{
|
||||
self.dataSource.gameTypeIdentifiers = [self.gameTypeIdentifier]
|
||||
}
|
||||
}
|
||||
|
||||
private let dataSource = GameCollectionViewDataSource()
|
||||
|
||||
required init?(coder aDecoder: NSCoder)
|
||||
{
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
self.dataSource.fetchedResultsController.delegate = self
|
||||
self.dataSource.cellConfigurationHandler = self.configureCell
|
||||
}
|
||||
|
||||
override func viewDidLoad()
|
||||
{
|
||||
super.viewDidLoad()
|
||||
|
||||
self.collectionView?.dataSource = self.dataSource
|
||||
self.collectionView?.delegate = self.dataSource
|
||||
|
||||
if let layout = self.collectionViewLayout as? GameCollectionViewLayout
|
||||
{
|
||||
layout.maximumBoxArtSize = CGSize(width: 100, height: 100)
|
||||
}
|
||||
}
|
||||
|
||||
override func viewWillAppear(animated: Bool)
|
||||
{
|
||||
self.dataSource.update()
|
||||
|
||||
super.viewWillAppear(animated)
|
||||
}
|
||||
|
||||
override func didReceiveMemoryWarning()
|
||||
{
|
||||
super.didReceiveMemoryWarning()
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
// MARK: - Navigation -
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
|
||||
{
|
||||
guard let viewController = segue.destinationViewController as? EmulationViewController else { return }
|
||||
|
||||
let indexPath = self.collectionView?.indexPathsForSelectedItems()?.first
|
||||
let game = self.dataSource.fetchedResultsController.objectAtIndexPath(indexPath!) as! Game
|
||||
|
||||
viewController.game = game
|
||||
}
|
||||
|
||||
// MARK: - Collection View -
|
||||
|
||||
private func configureCell(cell: GameCollectionViewCell, game: Game)
|
||||
{
|
||||
cell.nameLabel.text = game.name
|
||||
}
|
||||
}
|
||||
|
||||
extension GamesCollectionViewController: NSFetchedResultsControllerDelegate
|
||||
{
|
||||
func controllerDidChangeContent(controller: NSFetchedResultsController)
|
||||
{
|
||||
self.collectionView?.reloadData()
|
||||
}
|
||||
}
|
||||
@ -2,88 +2,49 @@
|
||||
// GamesViewController.swift
|
||||
// Delta
|
||||
//
|
||||
// Created by Riley Testut on 3/8/15.
|
||||
// Copyright (c) 2015 Riley Testut. All rights reserved.
|
||||
// Created by Riley Testut on 10/12/15.
|
||||
// Copyright © 2015 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import DeltaCore
|
||||
|
||||
class GamesViewController: UITableViewController
|
||||
import SNESDeltaCore
|
||||
|
||||
class GamesViewController: UIViewController
|
||||
{
|
||||
let directoryContentsDataSource: DirectoryContentsDataSource?
|
||||
var pageViewController: UIPageViewController! = nil
|
||||
|
||||
override init(style: UITableViewStyle)
|
||||
{
|
||||
if let documentsDirectoryURL = NSFileManager.defaultManager().URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask).first
|
||||
{
|
||||
self.directoryContentsDataSource = DirectoryContentsDataSource(directoryURL: documentsDirectoryURL)
|
||||
}
|
||||
else
|
||||
{
|
||||
self.directoryContentsDataSource = nil
|
||||
}
|
||||
|
||||
super.init(style: style)
|
||||
}
|
||||
let supportedGameTypeIdentifiers = [kUTTypeSNESGame as String]
|
||||
|
||||
required init?(coder aDecoder: NSCoder)
|
||||
{
|
||||
if let documentsDirectoryURL = NSFileManager.defaultManager().URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask).first
|
||||
{
|
||||
self.directoryContentsDataSource = DirectoryContentsDataSource(directoryURL: documentsDirectoryURL)
|
||||
}
|
||||
else
|
||||
{
|
||||
self.directoryContentsDataSource = nil
|
||||
}
|
||||
|
||||
super.init(coder: aDecoder)
|
||||
}
|
||||
|
||||
override func viewDidLoad()
|
||||
{
|
||||
super.viewDidLoad()
|
||||
|
||||
self.tableView.dataSource = self.directoryContentsDataSource
|
||||
self.automaticallyAdjustsScrollViewInsets = false
|
||||
|
||||
self.directoryContentsDataSource!.contentsUpdateHandler = {
|
||||
dispatch_async(dispatch_get_main_queue(), {
|
||||
self.tableView.reloadData()
|
||||
})
|
||||
}
|
||||
self.pageViewController = self.childViewControllers.first as? UIPageViewController
|
||||
self.pageViewController.dataSource = self
|
||||
self.pageViewController.delegate = self
|
||||
|
||||
self.directoryContentsDataSource?.cellConfigurationBlock = { (cell, indexPath, URL) in
|
||||
cell.textLabel?.text = URL.lastPathComponent
|
||||
}
|
||||
let viewController = self.viewControllerForIndex(0)
|
||||
self.pageViewController.setViewControllers([viewController], direction: .Forward, animated: false, completion: nil)
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
}
|
||||
|
||||
override func viewDidAppear(animated: Bool)
|
||||
override func viewDidLayoutSubviews()
|
||||
{
|
||||
super.viewDidAppear(animated)
|
||||
super.viewDidLayoutSubviews()
|
||||
|
||||
if self.directoryContentsDataSource == nil
|
||||
{
|
||||
let alertController = UIAlertController(title: NSLocalizedString("Invalid Games Directory", comment: ""), message: NSLocalizedString("Please ensure the current games directory exists, then restart Delta.", comment: ""), preferredStyle: .Alert)
|
||||
alertController.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: UIAlertActionStyle.Cancel, handler: nil))
|
||||
|
||||
self.presentViewController(alertController, animated: true, completion: nil)
|
||||
}
|
||||
let viewController = self.pageViewController.viewControllers?.first as! GamesCollectionViewController
|
||||
viewController.collectionView?.contentInset.top = self.topLayoutGuide.length
|
||||
}
|
||||
|
||||
override func didReceiveMemoryWarning()
|
||||
{
|
||||
override func didReceiveMemoryWarning() {
|
||||
super.didReceiveMemoryWarning()
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
//MARK: - Settings -
|
||||
|
||||
@IBAction func dismissSettingsViewController(segue: UIStoryboardSegue)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Importing -
|
||||
|
||||
@IBAction func importFiles()
|
||||
@ -92,13 +53,23 @@ class GamesViewController: UITableViewController
|
||||
gamePickerController.delegate = self
|
||||
self.presentGamePickerController(gamePickerController, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
|
||||
//MARK: UITableViewDelegate
|
||||
|
||||
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
|
||||
}
|
||||
|
||||
private extension GamesViewController
|
||||
{
|
||||
func viewControllerForIndex(index: Int) -> GamesCollectionViewController
|
||||
{
|
||||
var safeIndex = index % self.supportedGameTypeIdentifiers.count
|
||||
if safeIndex < 0
|
||||
{
|
||||
safeIndex = self.supportedGameTypeIdentifiers.count + safeIndex
|
||||
}
|
||||
|
||||
let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("gamesCollectionViewController") as! GamesCollectionViewController
|
||||
viewController.gameTypeIdentifier = self.supportedGameTypeIdentifiers[safeIndex] as String
|
||||
viewController.collectionView?.contentInset.top = self.topLayoutGuide.length
|
||||
|
||||
return viewController
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,7 +77,24 @@ extension GamesViewController: GamePickerControllerDelegate
|
||||
{
|
||||
func gamePickerController(gamePickerController: GamePickerController, didImportGames games: [Game])
|
||||
{
|
||||
DatabaseManager.sharedManager.save()
|
||||
print(games)
|
||||
}
|
||||
}
|
||||
|
||||
extension GamesViewController: UIPageViewControllerDelegate, UIPageViewControllerDataSource
|
||||
{
|
||||
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController?
|
||||
{
|
||||
let index = self.supportedGameTypeIdentifiers.indexOf((viewController as! GamesCollectionViewController).gameTypeIdentifier)
|
||||
let viewController = self.viewControllerForIndex(index! - 1)
|
||||
return viewController
|
||||
}
|
||||
|
||||
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController?
|
||||
{
|
||||
let index = self.supportedGameTypeIdentifiers.indexOf((viewController as! GamesCollectionViewController).gameTypeIdentifier)
|
||||
let viewController = self.viewControllerForIndex(index! + 1)
|
||||
return viewController
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,25 +1,109 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder.AppleTV.Storyboard" version="3.0" toolsVersion="9052" systemVersion="14F27" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" initialViewController="BYZ-38-t0r">
|
||||
<document type="com.apple.InterfaceBuilder.AppleTV.Storyboard" version="3.0" toolsVersion="9059" systemVersion="15A284" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" initialViewController="FTg-JN-aQ6">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9040"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9049"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<!--Game Selection View Controller-->
|
||||
<scene sceneID="yhk-9Q-4Ab">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="DeltaTV" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<collectionViewController id="CnX-3O-dQK" customClass="GameSelectionViewController" customModule="Delta" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" id="FJM-CE-KMj">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1920" height="1080"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
<animations/>
|
||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="50" minimumInteritemSpacing="50" id="Ixm-Mb-fwd" customClass="GameCollectionViewLayout" customModule="Delta" customModuleProvider="target">
|
||||
<size key="itemSize" width="130" height="130"/>
|
||||
<size key="headerReferenceSize" width="0.0" height="0.0"/>
|
||||
<size key="footerReferenceSize" width="0.0" height="0.0"/>
|
||||
<inset key="sectionInset" minX="120" minY="0.0" maxX="120" maxY="0.0"/>
|
||||
</collectionViewFlowLayout>
|
||||
<cells>
|
||||
<collectionViewCell opaque="NO" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="GameCell" id="6sa-FK-4f7" customClass="GameCollectionViewCell" customModule="Delta" customModuleProvider="target">
|
||||
<rect key="frame" x="120" y="145" width="130" height="130"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
||||
<rect key="frame" x="0.0" y="0.0" width="130" height="130"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<animations/>
|
||||
<connections>
|
||||
<segue destination="MrZ-ya-63l" kind="presentation" identifier="emulationViewControllerSegue" id="ksw-k4-XHA"/>
|
||||
</connections>
|
||||
</collectionViewCell>
|
||||
</cells>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="CnX-3O-dQK" id="ulM-rt-Xda"/>
|
||||
<outlet property="delegate" destination="CnX-3O-dQK" id="JnD-3l-mhK"/>
|
||||
</connections>
|
||||
</collectionView>
|
||||
<navigationItem key="navigationItem" id="sJW-TN-ta1">
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="add" id="82J-lt-vmM">
|
||||
<connections>
|
||||
<action selector="importFiles" destination="CnX-3O-dQK" id="KEb-1t-cKF"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
|
||||
</collectionViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="3Th-gg-1ub" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2958" y="172"/>
|
||||
</scene>
|
||||
<!--Emulation View Controller-->
|
||||
<scene sceneID="r5i-4h-mZc">
|
||||
<objects>
|
||||
<viewController id="MrZ-ya-63l" customClass="EmulationViewController" customModule="Delta" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="MM0-dd-mwD"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="b6h-eq-2Fc"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="kK5-qd-zj7">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1920" height="1080"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LCh-ID-K2p" customClass="GameView" customModule="DeltaCore">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1920" height="1080"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<constraints>
|
||||
<constraint firstItem="LCh-ID-K2p" firstAttribute="top" secondItem="MM0-dd-mwD" secondAttribute="bottom" id="4qb-eG-1PD"/>
|
||||
<constraint firstAttribute="trailing" secondItem="LCh-ID-K2p" secondAttribute="trailing" id="HCF-lu-VDh"/>
|
||||
<constraint firstItem="b6h-eq-2Fc" firstAttribute="top" secondItem="LCh-ID-K2p" secondAttribute="bottom" id="Hkw-DQ-adi"/>
|
||||
<constraint firstItem="LCh-ID-K2p" firstAttribute="leading" secondItem="kK5-qd-zj7" secondAttribute="leading" id="XhV-my-may"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="gameView" destination="LCh-ID-K2p" id="KJN-3P-cEc"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Nai-kK-05Z" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="5038" y="155"/>
|
||||
</scene>
|
||||
<!--Navigation Controller-->
|
||||
<scene sceneID="SXg-iY-y52">
|
||||
<objects>
|
||||
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="FTg-JN-aQ6" sceneMemberID="viewController">
|
||||
<toolbarItems/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="hum-xC-crg">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1920" height="145"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<animations/>
|
||||
</navigationBar>
|
||||
<nil name="viewControllers"/>
|
||||
<connections>
|
||||
<segue destination="CnX-3O-dQK" kind="relationship" relationship="rootViewController" id="Nou-hf-Uta"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="x2w-YH-UzS" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="770" y="180"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
|
||||
59
DeltaTV/EmulationViewController.swift
Normal file
59
DeltaTV/EmulationViewController.swift
Normal file
@ -0,0 +1,59 @@
|
||||
//
|
||||
// EmulationViewController.swift
|
||||
// Delta
|
||||
//
|
||||
// Created by Riley Testut on 10/11/15.
|
||||
// Copyright © 2015 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
import DeltaCore
|
||||
import SNESDeltaCore
|
||||
|
||||
class EmulationViewController: UIViewController
|
||||
{
|
||||
//MARK: - Properties -
|
||||
/** Properties **/
|
||||
var game: Game! {
|
||||
didSet
|
||||
{
|
||||
self.emulatorCore = SNESEmulatorCore(game: game)
|
||||
}
|
||||
}
|
||||
private(set) var emulatorCore: EmulatorCore!
|
||||
|
||||
//MARK: - Private Properties
|
||||
@IBOutlet private var gameView: GameView!
|
||||
|
||||
override func viewDidLoad()
|
||||
{
|
||||
super.viewDidLoad()
|
||||
|
||||
self.emulatorCore.addGameView(self.gameView)
|
||||
}
|
||||
|
||||
override func viewDidAppear(animated: Bool)
|
||||
{
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
self.emulatorCore.startEmulation()
|
||||
}
|
||||
|
||||
override func didReceiveMemoryWarning() {
|
||||
super.didReceiveMemoryWarning()
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// MARK: - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
|
||||
// Get the new view controller using segue.destinationViewController.
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
103
DeltaTV/GameSelectionViewController.swift
Normal file
103
DeltaTV/GameSelectionViewController.swift
Normal file
@ -0,0 +1,103 @@
|
||||
//
|
||||
// ViewController.swift
|
||||
// DeltaTV
|
||||
//
|
||||
// Created by Riley Testut on 9/26/15.
|
||||
// Copyright © 2015 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import CoreData
|
||||
|
||||
import SNESDeltaCore
|
||||
|
||||
class GameSelectionViewController: UICollectionViewController
|
||||
{
|
||||
private let dataSource = GameCollectionViewDataSource()
|
||||
|
||||
required init?(coder aDecoder: NSCoder)
|
||||
{
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
self.title = NSLocalizedString("Games", comment: "")
|
||||
|
||||
self.dataSource.gameTypeIdentifiers = [kUTTypeSNESGame as String]
|
||||
self.dataSource.fetchedResultsController.delegate = self
|
||||
self.dataSource.cellConfigurationHandler = self.configureCell
|
||||
}
|
||||
|
||||
override func viewDidLoad()
|
||||
{
|
||||
super.viewDidLoad()
|
||||
|
||||
self.collectionView?.dataSource = self.dataSource
|
||||
self.collectionView?.delegate = self.dataSource
|
||||
|
||||
if let layout = self.collectionViewLayout as? GameCollectionViewLayout
|
||||
{
|
||||
layout.maximumBoxArtSize = CGSize(width: 200, height: 200)
|
||||
}
|
||||
}
|
||||
|
||||
override func viewWillAppear(animated: Bool)
|
||||
{
|
||||
self.dataSource.update()
|
||||
|
||||
super.viewWillAppear(animated)
|
||||
}
|
||||
|
||||
override func didReceiveMemoryWarning()
|
||||
{
|
||||
super.didReceiveMemoryWarning()
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
// MARK: - Importing -
|
||||
|
||||
@IBAction func importFiles()
|
||||
{
|
||||
let gamePickerController = GamePickerController()
|
||||
gamePickerController.delegate = self
|
||||
self.presentGamePickerController(gamePickerController, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Navigation -
|
||||
|
||||
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
|
||||
{
|
||||
guard let viewController = segue.destinationViewController as? EmulationViewController else { return }
|
||||
|
||||
let indexPath = self.collectionView?.indexPathsForSelectedItems()?.first
|
||||
let game = self.dataSource.fetchedResultsController.objectAtIndexPath(indexPath!) as! Game
|
||||
|
||||
viewController.game = game
|
||||
}
|
||||
|
||||
// MARK: - Collection View -
|
||||
|
||||
private func configureCell(cell: GameCollectionViewCell, game: Game)
|
||||
{
|
||||
cell.nameLabel.font = UIFont.boldSystemFontOfSize(30)
|
||||
cell.nameLabel.text = game.name
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - <GamePickerControllerDelegate> -
|
||||
extension GameSelectionViewController: GamePickerControllerDelegate
|
||||
{
|
||||
func gamePickerController(gamePickerController: GamePickerController, didImportGames games: [Game])
|
||||
{
|
||||
DatabaseManager.sharedManager.save()
|
||||
print(games)
|
||||
}
|
||||
}
|
||||
|
||||
extension GameSelectionViewController: NSFetchedResultsControllerDelegate
|
||||
{
|
||||
func controllerDidChangeContent(controller: NSFetchedResultsController)
|
||||
{
|
||||
self.collectionView?.reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
//
|
||||
// ViewController.swift
|
||||
// DeltaTV
|
||||
//
|
||||
// Created by Riley Testut on 9/26/15.
|
||||
// Copyright © 2015 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class ViewController: UIViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
// Do any additional setup after loading the view, typically from a nib.
|
||||
}
|
||||
|
||||
override func didReceiveMemoryWarning() {
|
||||
super.didReceiveMemoryWarning()
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
12
Pods/Pods.xcodeproj/project.pbxproj
generated
12
Pods/Pods.xcodeproj/project.pbxproj
generated
@ -285,6 +285,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = DA312349A49333542E6F4B36B329960E /* Pods.release.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@ -300,7 +301,7 @@
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PODS_ROOT = "$(SRCROOT)";
|
||||
PRODUCT_NAME = Pods;
|
||||
SDKROOT = appletvos;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
@ -312,6 +313,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 087F6379BD69587FB559DDED4732D982 /* FileMD5Hash.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@ -324,7 +326,7 @@
|
||||
MODULEMAP_FILE = "Target Support Files/FileMD5Hash/FileMD5Hash.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
PRODUCT_NAME = FileMD5Hash;
|
||||
SDKROOT = appletvos;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
@ -336,6 +338,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 087F6379BD69587FB559DDED4732D982 /* FileMD5Hash.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@ -348,7 +351,7 @@
|
||||
MODULEMAP_FILE = "Target Support Files/FileMD5Hash/FileMD5Hash.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
PRODUCT_NAME = FileMD5Hash;
|
||||
SDKROOT = appletvos;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
@ -399,6 +402,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 977577C045EDA9D9D1F46E2598D19FC7 /* Pods.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@ -414,7 +418,7 @@
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PODS_ROOT = "$(SRCROOT)";
|
||||
PRODUCT_NAME = Pods;
|
||||
SDKROOT = appletvos;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
||||
BIN
Resources/Assets.xcassets/BoxArt.imageset/BoxArt-1.png
vendored
Normal file
BIN
Resources/Assets.xcassets/BoxArt.imageset/BoxArt-1.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
BIN
Resources/Assets.xcassets/BoxArt.imageset/BoxArt.png
vendored
Normal file
BIN
Resources/Assets.xcassets/BoxArt.imageset/BoxArt.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
BIN
Resources/Assets.xcassets/BoxArt.imageset/BoxArt@2x.png
vendored
Normal file
BIN
Resources/Assets.xcassets/BoxArt.imageset/BoxArt@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.3 KiB |
BIN
Resources/Assets.xcassets/BoxArt.imageset/BoxArt@3x.png
vendored
Normal file
BIN
Resources/Assets.xcassets/BoxArt.imageset/BoxArt@3x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
28
Resources/Assets.xcassets/BoxArt.imageset/Contents.json
vendored
Normal file
28
Resources/Assets.xcassets/BoxArt.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "BoxArt.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "BoxArt@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "BoxArt@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "tv",
|
||||
"filename" : "BoxArt-1.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user