├── handmadeAssets
├── .gitkeep
└── .gitignore
├── handmadeSrc
└── .gitkeep
├── Handmade Hero Dylib
├── handmadeSrc
└── Handmade Hero Dylib.xcodeproj
│ └── project.pbxproj
├── Handmade Hero OSX
├── Handmade Hero OSX
│ ├── handmadeSrc
│ ├── handmadeAssets
│ ├── Images.xcassets
│ │ └── AppIcon.appiconset
│ │ │ ├── hmhero512x512.jpeg
│ │ │ └── Contents.json
│ ├── Handmade Hero OSX-Bridging-Header.h
│ ├── Helpers.swift
│ ├── AppDelegate.swift
│ ├── Info.plist
│ ├── GameCodeLoader.swift
│ ├── PlatformLayer.swift
│ ├── ObjCShim.h
│ ├── SoundManager.swift
│ ├── Base.lproj
│ │ └── MainMenu.xib
│ ├── ObjCShim.m
│ ├── InputManager.swift
│ └── GameView.swift
├── Handmade Hero OSX.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── project.pbxproj
└── Handmade Hero OSXTests
│ ├── Info.plist
│ └── Handmade_Hero_OSXTests.swift
├── .gitignore
└── README.md
/handmadeAssets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/handmadeSrc/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/handmadeAssets/.gitignore:
--------------------------------------------------------------------------------
1 | test
2 |
--------------------------------------------------------------------------------
/Handmade Hero Dylib/handmadeSrc:
--------------------------------------------------------------------------------
1 | ../handmadeSrc/
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX/handmadeSrc:
--------------------------------------------------------------------------------
1 | ../../handmadeSrc/
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX/handmadeAssets:
--------------------------------------------------------------------------------
1 | ../../handmadeAssets/
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX/Images.xcassets/AppIcon.appiconset/hmhero512x512.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joekarl/swift_handmade_hero/HEAD/Handmade Hero OSX/Handmade Hero OSX/Images.xcassets/AppIcon.appiconset/hmhero512x512.jpeg
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 |
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.xccheckout
14 | *.moved-aside
15 | DerivedData
16 | *.hmap
17 | *.ipa
18 | *.xcuserstate
19 |
20 | # Handmade source
21 |
22 | handmadeSrc/*.cpp
23 | handmadeSrc/*.h
24 |
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX/Handmade Hero OSX-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Include all c headers that should be exposed to swift
3 | //
4 |
5 | // include opengl C calls
6 | #import
7 | #import
8 | #import
9 | #import
10 |
11 | // include IOKit/HID
12 | #import
13 |
14 | // include platform layer header
15 | #import "handmadeSrc/handmade_platform.h"
16 |
17 | // include the obj shims
18 | #import "ObjCShim.h"
19 |
20 | // include dylib handling code
21 | #import
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX/Helpers.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Helpers.swift
3 | // Handmade Hero Swift Platform
4 | //
5 | // Created by Karl Kirch on 12/25/14.
6 | // Copyright (c) 2014 Handmade Hero. All rights reserved.
7 | //
8 |
9 | class Helpers {
10 |
11 | class func kilobytes(m: uint64) -> uint64 {
12 | return m * 1024
13 | }
14 |
15 | class func megabytes(m: uint64) -> uint64 {
16 | return kilobytes(m) * 1024
17 | }
18 |
19 | class func gigabytes(m: uint64) -> uint64 {
20 | return megabytes(m) * 1024
21 | }
22 | }
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSXTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.handmadehero.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSXTests/Handmade_Hero_OSXTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Handmade_Hero_OSXTests.swift
3 | // Handmade Hero OSXTests
4 | //
5 | // Created by Karl Kirch on 12/28/14.
6 | // Copyright (c) 2014 Handmade Hero. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 | import XCTest
11 |
12 | class Handmade_Hero_OSXTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | XCTAssert(true, "Pass")
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measureBlock() {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Handmade Hero OSX
4 | //
5 | // Created by Karl Kirch on 12/28/14.
6 | // Copyright (c) 2014 Handmade Hero. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | @NSApplicationMain
12 | class AppDelegate: NSObject, NSApplicationDelegate {
13 |
14 | @IBOutlet weak var window: NSWindow!
15 | @IBOutlet weak var gameView: GameView!
16 |
17 |
18 | func applicationDidFinishLaunching(aNotification: NSNotification) {
19 | // Insert code here to initialize your application
20 | window.aspectRatio = window.frame.size;
21 | }
22 |
23 | func applicationWillTerminate(aNotification: NSNotification) {
24 | // Insert code here to tear down your application
25 | }
26 |
27 | func applicationShouldTerminateAfterLastWindowClosed(sender: NSApplication) -> Bool {
28 | return true
29 | }
30 |
31 |
32 | func applicationDidBecomeActive(notification: NSNotification) {
33 | gameView.setAppIsActive(true)
34 | }
35 |
36 | func applicationDidResignActive(notification: NSNotification) {
37 | gameView.setAppIsActive(false)
38 | }
39 |
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX/Images.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 | "size" : "512x512",
45 | "idiom" : "mac",
46 | "filename" : "hmhero512x512.jpeg",
47 | "scale" : "1x"
48 | },
49 | {
50 | "idiom" : "mac",
51 | "size" : "512x512",
52 | "scale" : "2x"
53 | }
54 | ],
55 | "info" : {
56 | "version" : 1,
57 | "author" : "xcode"
58 | }
59 | }
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | com.handmadehero.$(PRODUCT_NAME:rfc1034identifier)
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 © 2014 Handmade Hero. All rights reserved.
29 | NSMainNibFile
30 | MainMenu
31 | NSPrincipalClass
32 | NSApplication
33 |
34 |
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ##Handmade Hero Swift Cocoa Platform Layer
2 |
3 | This is an ongoing OSX version of a platform layer for Casey Muratori's Handmade Hero.
4 |
5 | The goal is to be able to drop in Casey's platform independent game source code and compile and run it unchanged.
6 |
7 | ###Xcode
8 | I'm using xcode 6.1.1 on OSX 10.9.5. This targets 10.9 using the OSX 10.10 SDK.
9 |
10 | ###dylib support
11 | The platform independent layer is wrapped up in a dylib and is loaded dynamically by the platform layer. This allows the code to be reloaded at runtime by simply building the dylib. Due to the way xcode projects work, this is as simple as building the main project (⌘-b or ⌘-⏎-b).
12 |
13 | Ultimately how this works is the main project has the dylib as a compile dependency. A copy files build phase is setup to copy the dylib (once built) into the frameworks folder of our resulting app. The platform layer looks for this the dylib at runtime and checks to see whether the dylib has been updated. If it has been updated, it reloads the dylib.
14 |
15 | ###Game input
16 | Right now this just supports keyboard input but has the beginnings of controller support (turns out this is just super messy on OSX).
17 |
18 | As of right now, the controls are wasd for movement and you can also press the up arrow to speed up movement.
19 |
20 | To connect to the game initially, press the space bar.
21 |
22 | ###Swift ObjC shim
23 | So Swift is nice and all, but any API that takes a function pointer or needs to invoke the function behind a function pointer cannot be implemented in Swift. This is just a limitation of the language. So what you will find in this code is an ObjcShim file which is where anything that can't be done in Swift will reside. Some of these things just forward calls from the objc shim back in to the Swift layer, others will be invoked by the Swift layer to forward calls from the Swift layer into the platform independent layer.
24 |
25 | ####IMPORTANT
26 |
27 | I removed Casey's platform-independent game code from this repository. At the moment that is just handmade*.cpp and handmade*.h files.
28 |
29 | Once you clone or update from this repository, copy over the handmade .cpp/.h files from Casey's source code into the handmadeSrc folder (don't copy the platform layer files, just the platform independent files).
30 | You also need to copy over the assets into the handmadeAssets folder. For this copy the entire contents of the assets zip into the assets folder (should end up with a handmadeAssets/test/*.bmp folder structure)
31 |
32 | This repository works with Casey's handmade*.cpp/handmade*.h files from handmade_hero_050_source.
33 |
34 | ####Author
35 |
36 | Karl Kirch
37 |
38 | Handmade Hero is being created by Casey Muratori.
39 |
40 | You can find more information about Handmade Hero at: http://handmadehero.org
41 |
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX/GameCodeLoader.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GameCode.swift
3 | // Handmade Hero Swift Platform
4 | //
5 | // Created by Karl Kirch on 12/26/14.
6 | // Copyright (c) 2014 Handmade Hero. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class GameCodeLoader {
12 | var gameUpdateAndRenderFn = CFunctionPointer.null()
13 | var gameGetSoundSamplesFn = CFunctionPointer.null()
14 | var isInitialized = false
15 | let dylibPath: String
16 | var lastLoadTime = NSDate()
17 | var dylibRef = UnsafeMutablePointer.null()
18 |
19 | init() {
20 | let frameworksPath = NSBundle.mainBundle().privateFrameworksPath
21 | let dylibName = "libHandmade Hero Dylib.dylib"
22 | dylibPath = frameworksPath! + "/" + dylibName
23 | }
24 |
25 | func reloadGameCodeIfNeeded() -> Bool {
26 | if (!isInitialized) {
27 | NSLog("ERROR: Must call loadGameCode before calling reloadGameCodeIfNeeded")
28 | abort()
29 | }
30 |
31 | var err = NSErrorPointer()
32 | var attributes = NSFileManager.defaultManager().attributesOfItemAtPath(dylibPath, error: err)
33 | if (attributes == nil) {
34 | return false
35 | }
36 | var currentLoadTime = attributes![NSFileModificationDate]! as NSDate
37 | if (currentLoadTime.compare(lastLoadTime) == NSComparisonResult.OrderedDescending) {
38 | // ie currentLoadTime > lastLoadTime
39 | lastLoadTime = currentLoadTime
40 | unloadGameCode()
41 | return loadGameCode()
42 | } else {
43 | return false
44 | }
45 | }
46 |
47 | func loadGameCode() -> Bool {
48 | var didLoadCorrectly = false
49 |
50 | dylibRef = dlopen(dylibPath, RTLD_LAZY | RTLD_LOCAL)
51 | if (dylibRef != UnsafeMutablePointer.null()) {
52 | gameUpdateAndRenderFn = unsafeBitCast(dlsym(dylibRef, "GameUpdateAndRender"), CFunctionPointer.self)
53 | gameGetSoundSamplesFn = unsafeBitCast(dlsym(dylibRef, "GameGetSoundSamples"), CFunctionPointer.self)
54 |
55 | if (gameUpdateAndRenderFn != CFunctionPointer.null()
56 | && gameGetSoundSamplesFn != CFunctionPointer.null()) {
57 | didLoadCorrectly = true
58 | }
59 | }
60 |
61 | if (didLoadCorrectly) {
62 | NSLog("Successfully loaded game code")
63 | isInitialized = true
64 | } else {
65 | unloadGameCode()
66 | NSLog("WARNING: Failed to load game code")
67 | }
68 | return isInitialized
69 | }
70 |
71 | func unloadGameCode() {
72 | isInitialized = false
73 |
74 | if (dylibRef != UnsafeMutablePointer.null()) {
75 | dlclose(dylibRef)
76 | dylibRef = UnsafeMutablePointer.null()
77 | }
78 |
79 | // null out our pointers for good measure...
80 | gameUpdateAndRenderFn = CFunctionPointer.null()
81 | gameGetSoundSamplesFn = CFunctionPointer.null()
82 | }
83 | }
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX/PlatformLayer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PlatformLayer.swift
3 | // Handmade Hero Swift Platform
4 | //
5 | // Created by Karl Kirch on 12/26/14.
6 | // Copyright (c) 2014 Handmade Hero. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class PlatformLayer {
12 |
13 | // uninitialized pointers to our platform layer memory
14 | var gameMemory = UnsafeMutablePointer.alloc(1)
15 | var gameInput = UnsafeMutablePointer.alloc(1)
16 | var gameOffscreenBuffer = UnsafeMutablePointer.alloc(1)
17 | var gameThreadContext = UnsafeMutablePointer.null()
18 |
19 | // game code loader
20 | private var gameCodeLoader = GameCodeLoader()
21 |
22 | // input manager
23 | private let inputManager: InputManager
24 | private let soundManager = SoundManager()
25 |
26 | init(anInputManager: InputManager) {
27 | inputManager = anInputManager
28 |
29 | // initialize all of our memory
30 | let permanantStorageSize = Helpers.megabytes(64)
31 | let TransientStorageSize = Helpers.gigabytes(1)
32 | gameMemory.memory.PermanentStorageSize = permanantStorageSize
33 | gameMemory.memory.TransientStorageSize = TransientStorageSize
34 | gameMemory.memory.PermanentStorage = UnsafeMutablePointer.alloc(Int(permanantStorageSize))
35 | gameMemory.memory.TransientStorage = UnsafeMutablePointer.alloc(Int(TransientStorageSize))
36 | gameMemory.memory.DEBUGPlatformFreeFileMemory = getFreeFileFn()
37 | gameMemory.memory.DEBUGPlatformReadEntireFile = getReadFileFn()
38 | gameMemory.memory.DEBUGPlatformWriteEntireFile = getWriteFileFn()
39 |
40 | gameOffscreenBuffer.memory.Width = 960 /*magic value*/
41 | gameOffscreenBuffer.memory.Height = 540 /*magic value*/
42 | gameOffscreenBuffer.memory.BytesPerPixel = 4 /*magic value*/
43 | gameOffscreenBuffer.memory.Pitch = gameOffscreenBuffer.memory.Width * gameOffscreenBuffer.memory.BytesPerPixel
44 |
45 | var totalBufferSize = gameOffscreenBuffer.memory.Pitch * gameOffscreenBuffer.memory.Height
46 | gameOffscreenBuffer.memory.Memory = UnsafeMutablePointer.alloc(Int(totalBufferSize))
47 |
48 | // load our dylib game code
49 | gameCodeLoader.loadGameCode()
50 | }
51 |
52 | func platformGameUpdateAndRender(targetFrameTime: real32) {
53 | // reload our dylib if it's changed
54 | gameCodeLoader.reloadGameCodeIfNeeded()
55 |
56 | // update input state
57 | inputManager.updateInputState(gameInput)
58 |
59 | // have to do this every frame because of me copying over all of the input state :/
60 | // TODO: get this value from display link
61 | gameInput.memory.dtForFrame = targetFrameTime
62 |
63 | // sanity check
64 | if (gameCodeLoader.isInitialized) {
65 | // run function pointer in objc b/c swift can't call function pointers o_0
66 | shimCallGameUpdateAndRenderFn(gameCodeLoader.gameUpdateAndRenderFn, gameThreadContext, gameMemory, gameInput, gameOffscreenBuffer)
67 |
68 | // delegate sound handling to sound manager
69 | soundManager.updateAudioBuffer(gameCodeLoader.gameGetSoundSamplesFn, threadContext: gameThreadContext, gameMemory: gameMemory)
70 | }
71 | }
72 | }
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX/ObjCShim.h:
--------------------------------------------------------------------------------
1 | //
2 | // ObjcShim.h
3 | // Handmade Hero Swift Platform
4 | //
5 | // Created by Karl Kirch on 12/23/14.
6 | // Copyright (c) 2014 Handmade Hero. All rights reserved.
7 | //
8 |
9 | #ifndef Handmade_Hero_Swift_Platform_DisplayLinkShim_h
10 | #define Handmade_Hero_Swift_Platform_DisplayLinkShim_h
11 |
12 | #import
13 | #import
14 | #import
15 | #include "handmade_platform.h"
16 |
17 | // Display link shims
18 | CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *now,
19 | const CVTimeStamp *outputTime, CVOptionFlags flagsIn,
20 | CVOptionFlags *flagsOut, void *displayLinkContext);
21 | CVDisplayLinkOutputCallback getDisplayLinkCallback();
22 |
23 | // Core Audio shims
24 | OSStatus coreAudioCallback(void* inRefCon,
25 | AudioUnitRenderActionFlags* ioActionFlags,
26 | const AudioTimeStamp* inTimeStamp,
27 | UInt32 inBusNumber,
28 | UInt32 inNumberFrames,
29 | AudioBufferList* ioData);
30 | AURenderCallback getCoreAudioCallback();
31 |
32 | // Platform indepent layer shims
33 | void shimCallGameUpdateAndRenderFn(game_update_and_render fn,
34 | thread_context* threadContext,
35 | game_memory* memory,
36 | game_input* input,
37 | game_offscreen_buffer* buffer);
38 |
39 | void shimCallGameGetSoundSamplesFn(game_get_sound_samples fn,
40 | thread_context* threadContext,
41 | game_memory* memory,
42 | game_sound_output_buffer* buffer);
43 |
44 | // HID lib shims
45 | void hidDeviceAdded(void* context, IOReturn result, void* sender, IOHIDDeviceRef device);
46 | void hidDeviceRemoved(void* context, IOReturn result, void* sender, IOHIDDeviceRef device);
47 | void hidDeviceAction(void* context, IOReturn result, void* sender, IOHIDValueRef value);
48 | IOHIDDeviceCallback getHidDeviceAddedCallback();
49 | IOHIDDeviceCallback getHidDeviceRemovedCallback();
50 | IOHIDValueCallback getHidDeviceActionCallback();
51 |
52 | // game_controller_input shim due to lack of union support in swift :/
53 | typedef struct game_controller_input_shim {
54 | bool32 IsConnected;
55 | bool32 IsAnalog;
56 | real32 StickAverageX;
57 | real32 StickAverageY;
58 | game_button_state MoveUp;
59 | game_button_state MoveDown;
60 | game_button_state MoveLeft;
61 | game_button_state MoveRight;
62 |
63 | game_button_state ActionUp;
64 | game_button_state ActionDown;
65 | game_button_state ActionLeft;
66 | game_button_state ActionRight;
67 |
68 | game_button_state LeftShoulder;
69 | game_button_state RightShoulder;
70 |
71 | game_button_state Back;
72 | game_button_state Start;
73 |
74 | // NOTE(casey): All buttons must be added above this line
75 |
76 | game_button_state Terminator;
77 | } game_controller_input_shim;
78 |
79 | game_controller_input_shim * unsafeControllerInputCast(game_input * input, int controller);
80 |
81 | // Get debug file read callbacks
82 | debug_platform_read_entire_file* getReadFileFn();
83 | debug_platform_write_entire_file* getWriteFileFn();
84 | debug_platform_free_file_memory* getFreeFileFn();
85 |
86 | #endif
87 |
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX/SoundManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SoundManager.swift
3 | // Handmade Hero OSX
4 | //
5 | // Created by Karl Kirch on 12/31/14.
6 | // Copyright (c) 2014 Handmade Hero. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import AudioUnit
11 |
12 | @objc class SoundManager {
13 |
14 | // sound buffer that the game will use
15 | private let soundBuffer = UnsafeMutablePointer.alloc(1)
16 |
17 | // Lock for synchronizing between core audio thread and other threads
18 | private let audioLock = NSLock()
19 |
20 | init() {
21 | let samplesPerSec = 4800
22 | let bytesPerSample = sizeof(int16) * 2
23 | let numberOfSamples = bytesPerSample * samplesPerSec
24 | soundBuffer.memory.SamplesPerSecond = int32(samplesPerSec)
25 | soundBuffer.memory.SampleCount = 0
26 | soundBuffer.memory.Samples = UnsafeMutablePointer.alloc(numberOfSamples)
27 |
28 | // init core audio
29 | let audioComponentDescription = UnsafeMutablePointer.alloc(1)
30 | audioComponentDescription.memory.componentType = OSType(kAudioUnitType_Output)
31 | audioComponentDescription.memory.componentSubType = OSType(kAudioUnitSubType_DefaultOutput)
32 | audioComponentDescription.memory.componentManufacturer = OSType(kAudioUnitManufacturer_Apple)
33 |
34 | let outputComponent = AudioComponentFindNext(nil, audioComponentDescription)
35 | let audioUnit = UnsafeMutablePointer.alloc(1)
36 |
37 | AudioComponentInstanceNew(outputComponent, audioUnit)
38 | AudioUnitInitialize(audioUnit.memory)
39 |
40 | let audioStreamBasicDescription = UnsafeMutablePointer.alloc(1)
41 | audioStreamBasicDescription.memory.mSampleRate = Float64(soundBuffer.memory.SamplesPerSecond)
42 | audioStreamBasicDescription.memory.mFormatID = AudioFormatID(kAudioFormatLinearPCM)
43 | audioStreamBasicDescription.memory.mFormatFlags = AudioFormatFlags(kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked)
44 | audioStreamBasicDescription.memory.mChannelsPerFrame = 2
45 | audioStreamBasicDescription.memory.mBitsPerChannel = 16
46 | audioStreamBasicDescription.memory.mBytesPerPacket = 4
47 | audioStreamBasicDescription.memory.mBytesPerFrame = 4
48 |
49 | AudioUnitSetProperty(audioUnit.memory, AudioUnitPropertyID(kAudioUnitProperty_StreamFormat), AudioUnitScope(kAudioUnitScope_Input), 0, audioStreamBasicDescription, UInt32(sizeof(AudioStreamBasicDescription)))
50 |
51 | let caContext = unsafeBitCast(self, UnsafeMutablePointer.self)
52 | let audioUnitCallbacks = UnsafeMutablePointer.alloc(1)
53 | audioUnitCallbacks.memory.inputProc = getCoreAudioCallback()
54 | audioUnitCallbacks.memory.inputProcRefCon = caContext
55 |
56 | AudioUnitSetProperty(audioUnit.memory, AudioUnitPropertyID(kAudioUnitProperty_SetRenderCallback), AudioUnitScope(kAudioUnitScope_Global), 0, audioUnitCallbacks, UInt32(sizeof(AURenderCallbackStruct)))
57 |
58 | //AudioOutputUnitStart(audioUnit.memory);
59 | }
60 |
61 | func updateAudioBuffer(sampleGameAudioFn: CFunctionPointer, threadContext: UnsafeMutablePointer, gameMemory: UnsafeMutablePointer) {
62 | audioLock.lock()
63 | shimCallGameGetSoundSamplesFn(sampleGameAudioFn, threadContext, gameMemory, soundBuffer)
64 | audioLock.unlock()
65 | }
66 |
67 | func coreAudioCallback(inRefCon: UnsafeMutablePointer, ioActionFlags: UnsafeMutablePointer, inTimeStamp: UnsafePointer, inBusNumber: UInt32, inNumberFrames: UInt32, ioData: UnsafeMutablePointer) -> OSStatus{
68 |
69 | audioLock.lock()
70 |
71 | audioLock.unlock()
72 | return noErr
73 | }
74 | }
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX/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 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX/ObjCShim.m:
--------------------------------------------------------------------------------
1 | //
2 | // ObjCShim.m
3 | // Handmade Hero Swift Platform
4 | //
5 | // Created by Karl Kirch on 12/23/14.
6 | // Copyright (c) 2014 Handmade Hero. All rights reserved.
7 | //
8 |
9 | #import "ObjCShim.h"
10 |
11 | // Imports the generated bridge from objc to swift
12 | // This is available after setting Defines Module to YES in the Build Settings for the project
13 | #import "Handmade_Hero_OSX-Swift.h"
14 |
15 | CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *now,
16 | const CVTimeStamp *outputTime, CVOptionFlags flagsIn,
17 | CVOptionFlags *flagsOut, void *displayLinkContext)
18 | {
19 | // wrap our call to swift in an autorelease pool because the cvdisplaylink thread doesn't
20 | // have an autorelease pool by default
21 | @autoreleasepool {
22 | [(__bridge GameView*)displayLinkContext getFrame:outputTime];
23 | }
24 |
25 | return kCVReturnSuccess;
26 | }
27 |
28 | CVDisplayLinkOutputCallback getDisplayLinkCallback()
29 | {
30 | return displayLinkCallback;
31 | }
32 |
33 | OSStatus coreAudioCallback(void* inRefCon,
34 | AudioUnitRenderActionFlags* ioActionFlags,
35 | const AudioTimeStamp* inTimeStamp,
36 | UInt32 inBusNumber,
37 | UInt32 inNumberFrames,
38 | AudioBufferList* ioData)
39 | {
40 | return [(__bridge SoundManager*)inRefCon coreAudioCallback:inRefCon ioActionFlags:ioActionFlags inTimeStamp:inTimeStamp inBusNumber:inBusNumber inNumberFrames:inNumberFrames ioData:ioData];
41 | }
42 |
43 | AURenderCallback getCoreAudioCallback()
44 | {
45 | return coreAudioCallback;
46 | }
47 |
48 | void shimCallGameUpdateAndRenderFn(game_update_and_render fn,
49 | thread_context* threadContext,
50 | game_memory* memory,
51 | game_input* input,
52 | game_offscreen_buffer* buffer)
53 | {
54 | fn(threadContext, memory, input, buffer);
55 | }
56 |
57 | void shimCallGameGetSoundSamplesFn(game_get_sound_samples fn,
58 | thread_context* threadContext,
59 | game_memory* memory,
60 | game_sound_output_buffer* buffer)
61 | {
62 | fn(threadContext, memory, buffer);
63 | }
64 |
65 | void hidDeviceAdded(void* context, IOReturn result, void* sender, IOHIDDeviceRef device)
66 | {
67 | [(__bridge InputManager*)context hidDeviceAdded:context result:result sender:sender device:device];
68 | }
69 |
70 | void hidDeviceRemoved(void* context, IOReturn result, void* sender, IOHIDDeviceRef device)
71 | {
72 | [(__bridge InputManager*)context hidDeviceRemoved:context result:result sender:sender device:device];
73 | }
74 |
75 | void hidDeviceAction(void* context, IOReturn result, void* sender, IOHIDValueRef value)
76 | {
77 | [(__bridge InputManager*)context hidDeviceAction:context result:result sender:sender value:value];
78 | }
79 |
80 | IOHIDDeviceCallback getHidDeviceAddedCallback()
81 | {
82 | return hidDeviceAdded;
83 | }
84 |
85 | IOHIDDeviceCallback getHidDeviceRemovedCallback()
86 | {
87 | return hidDeviceRemoved;
88 | }
89 |
90 | IOHIDValueCallback getHidDeviceActionCallback()
91 | {
92 | return hidDeviceAction;
93 | }
94 |
95 | game_controller_input_shim * unsafeControllerInputCast(game_input * input, int controller)
96 | {
97 | return (game_controller_input_shim *) &input->Controllers[controller];
98 | }
99 |
100 | // TODO write all this in swift and shim it
101 | DEBUG_PLATFORM_FREE_FILE_MEMORY(DEBUGPlatformFreeFileMemory)
102 | {
103 | if (Memory)
104 | {
105 | free(Memory);
106 | }
107 | }
108 |
109 | // TODO write all this in swift and shim it
110 | DEBUG_PLATFORM_READ_ENTIRE_FILE(DEBUGPlatformReadEntireFile)
111 | {
112 | debug_read_file_result Result = {};
113 |
114 | NSString *frameworksPath = [[NSBundle mainBundle] resourcePath];
115 | NSString *filePath = [NSString stringWithFormat:@"%@/%s", frameworksPath, Filename];
116 |
117 | int fd = open([filePath cStringUsingEncoding:NSUTF8StringEncoding], O_RDONLY);
118 | if (fd != -1)
119 | {
120 | struct stat fileStat;
121 | if (fstat(fd, &fileStat) == 0)
122 | {
123 | uint32 FileSize32 = fileStat.st_size;
124 |
125 | kern_return_t result = vm_allocate((vm_map_t)mach_task_self(),
126 | (vm_address_t*)&Result.Contents,
127 | FileSize32,
128 | VM_FLAGS_ANYWHERE);
129 | if ((result == KERN_SUCCESS) && Result.Contents)
130 | {
131 | ssize_t BytesRead;
132 | BytesRead = read(fd, Result.Contents, FileSize32);
133 | if (BytesRead == FileSize32) // should have read until EOF
134 | {
135 | Result.ContentsSize = FileSize32;
136 | }
137 | else
138 | {
139 | DEBUGPlatformFreeFileMemory(Thread, Result.Contents);
140 | Result.Contents = 0;
141 | }
142 | }
143 | else
144 | {
145 | printf("DEBUGPlatformReadEntireFile %s: vm_allocate error: %d: %s\n",
146 | Filename, errno, strerror(errno));
147 | }
148 | }
149 | else
150 | {
151 | printf("DEBUGPlatformReadEntireFile %s: fstat error: %d: %s\n",
152 | Filename, errno, strerror(errno));
153 | }
154 |
155 | close(fd);
156 | }
157 | else
158 | {
159 | printf("DEBUGPlatformReadEntireFile %s: open error: %d: %s\n",
160 | Filename, errno, strerror(errno));
161 | }
162 |
163 | return Result;
164 | }
165 |
166 | // TODO write all this in swift and shim it
167 | DEBUG_PLATFORM_WRITE_ENTIRE_FILE(DEBUGPlatformWriteEntireFile)
168 | {
169 | bool32 Result = false;
170 |
171 | NSString *frameworksPath = [[NSBundle mainBundle] resourcePath];
172 | NSString *filePath = [NSString stringWithFormat:@"%@/%s", frameworksPath, Filename];
173 |
174 | int fd = open([filePath cStringUsingEncoding:NSUTF8StringEncoding], O_WRONLY | O_CREAT, 0644);
175 | if (fd != -1)
176 | {
177 | ssize_t BytesWritten = write(fd, Memory, MemorySize);
178 | Result = (BytesWritten == MemorySize);
179 |
180 | if (!Result)
181 | {
182 |
183 | }
184 |
185 | close(fd);
186 | }
187 | else
188 | {
189 | }
190 |
191 | return Result;
192 | }
193 |
194 | debug_platform_read_entire_file* getReadFileFn()
195 | {
196 | return DEBUGPlatformReadEntireFile;
197 | }
198 |
199 | debug_platform_write_entire_file* getWriteFileFn()
200 | {
201 | return DEBUGPlatformWriteEntireFile;
202 | }
203 |
204 | debug_platform_free_file_memory* getFreeFileFn()
205 | {
206 | return DEBUGPlatformFreeFileMemory;
207 | }
208 |
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX/InputManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InputManager.swift
3 | // Handmade Hero Swift Platform
4 | //
5 | // Created by Karl Kirch on 12/27/14.
6 | // Copyright (c) 2014 Handmade Hero. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | @objc class InputManager {
12 |
13 | // lock for thread safety
14 | private let inputLock = NSLock()
15 |
16 | // local copy of input
17 | private var input = UnsafeMutablePointer.alloc(1)
18 |
19 | private var hidManager: Unmanaged
20 |
21 | var shouldProcessInput = true
22 |
23 | init() {
24 | //assume keyboard always connected
25 | input.memory.Controllers.0.IsConnected = 1
26 |
27 | hidManager = IOHIDManagerCreate(kCFAllocatorDefault, IOOptionBits(kIOHIDOptionsTypeNone));
28 |
29 | let hidContext = unsafeBitCast(self, UnsafeMutablePointer.self)
30 | let hidManagerVal = hidManager.takeUnretainedValue();
31 | // device types we want to monitor
32 | let deviceCriteria = [
33 | [
34 | kIOHIDDeviceUsagePageKey: kHIDPage_GenericDesktop,
35 | kIOHIDDeviceUsageKey: kHIDUsage_GD_Joystick
36 | ],
37 | [
38 | kIOHIDDeviceUsagePageKey: kHIDPage_GenericDesktop,
39 | kIOHIDDeviceUsageKey: kHIDUsage_GD_GamePad
40 | ],
41 | [
42 | kIOHIDDeviceUsagePageKey: kHIDPage_GenericDesktop,
43 | kIOHIDDeviceUsageKey: kHIDUsage_GD_MultiAxisController
44 | ],
45 | [
46 | kIOHIDDeviceUsagePageKey: kHIDPage_GenericDesktop,
47 | kIOHIDDeviceUsageKey: kHIDUsage_GD_Keyboard
48 | ]
49 | ]
50 | IOHIDManagerSetDeviceMatchingMultiple(hidManagerVal, deviceCriteria)
51 | IOHIDManagerRegisterDeviceMatchingCallback(hidManagerVal, getHidDeviceAddedCallback(), hidContext);
52 | IOHIDManagerRegisterDeviceRemovalCallback(hidManagerVal, getHidDeviceRemovedCallback(), hidContext);
53 | IOHIDManagerScheduleWithRunLoop(hidManagerVal, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)
54 | IOHIDManagerOpen(hidManagerVal, IOOptionBits(kIOHIDOptionsTypeNone))
55 | IOHIDManagerRegisterInputValueCallback(hidManagerVal, getHidDeviceActionCallback(), hidContext);
56 | }
57 |
58 | func updateInputState(inputPtr: UnsafeMutablePointer) {
59 | inputLock.lock()
60 | memcpy(inputPtr, input, UInt(sizeof(game_input)))
61 | inputLock.unlock()
62 | }
63 |
64 | func hidDeviceAdded(context: UnsafeMutablePointer, result: IOReturn, sender: UnsafeMutablePointer, device: IOHIDDevice) {
65 | var manufacturer = "Unknown"
66 | // let mfnTypeRef: AnyObject = IOHIDDeviceGetProperty(device, kIOHIDManufacturerKey).takeUnretainedValue()
67 | // if (unsafeBitCast(mfnTypeRef, CFStringRef.self) != nil) {
68 | // manufacturer = unsafeBitCast(mfnTypeRef, CFStringRef.self) as String
69 | // }
70 |
71 | var product = "Unknown"
72 | let prodTypeRef: AnyObject = IOHIDDeviceGetProperty(device, kIOHIDProductKey).takeUnretainedValue()
73 | if (unsafeBitCast(prodTypeRef, CFStringRef.self) != nil) {
74 | product = unsafeBitCast(prodTypeRef, CFStringRef.self) as String
75 | }
76 |
77 | NSLog("Device added %@ %@", manufacturer, product)
78 | }
79 |
80 | func hidDeviceRemoved(context: UnsafeMutablePointer, result: IOReturn, sender: UnsafeMutablePointer, device: IOHIDDevice) {
81 | var manufacturer = "Unknown"
82 | // let mfnTypeRef: AnyObject = IOHIDDeviceGetProperty(device, kIOHIDManufacturerKey).takeUnretainedValue()
83 | // if (unsafeBitCast(mfnTypeRef, CFStringRef.self) != nil) {
84 | // manufacturer = unsafeBitCast(mfnTypeRef, CFStringRef.self) as String
85 | // }
86 |
87 | var product = "Unknown"
88 | let prodTypeRef: AnyObject = IOHIDDeviceGetProperty(device, kIOHIDProductKey).takeUnretainedValue()
89 | if (unsafeBitCast(prodTypeRef, CFStringRef.self) != nil) {
90 | product = unsafeBitCast(prodTypeRef, CFStringRef.self) as String
91 | }
92 |
93 | NSLog("Device removed %@ %@", manufacturer, product)
94 | }
95 |
96 | func hidDeviceAction(context: UnsafeMutablePointer, result: IOReturn, sender: UnsafeMutablePointer, value: IOHIDValueRef) {
97 | // make sure we should actually record our input
98 | // TODO: this should probably be more than a boolean
99 | // so that we can reset all input on window inactive
100 | if (!shouldProcessInput) {
101 | return
102 | }
103 |
104 | // PS3 controllers report bogus values
105 | // just throw them away
106 | // via itfrombit
107 | // https://github.com/itfrombit/osx_handmade/blob/master/Handmade%20Hero/HandmadeView.mm#L336-L337
108 | if (IOHIDValueGetLength(value) > 2)
109 | {
110 | //NSLog("OSXHIDAction: value length > 2: %ld", IOHIDValueGetLength(value));
111 | return
112 | }
113 |
114 | inputLock.lock()
115 |
116 | let element = IOHIDValueGetElement(value)
117 | let elementValue = IOHIDValueGetIntegerValue(value);
118 | let usagePage = Int(IOHIDElementGetUsagePage(element.takeUnretainedValue()))
119 | let usage = Int(IOHIDElementGetUsage(element.takeUnretainedValue()))
120 |
121 | switch(usagePage) {
122 | case kHIDPage_KeyboardOrKeypad:
123 | handleKeyboardInput(usage, isDown: elementValue == 1);
124 | break
125 | default:
126 | if (usage == 0x01 || (usage >= 0x30 && usage <= 0x35)) {
127 | break
128 | }
129 | NSLog("Unhandled usagePage %02x usage %02x val %02x", usagePage, usage, elementValue)
130 | break
131 | }
132 |
133 | inputLock.unlock()
134 | }
135 |
136 | private func handleKeyboardInput(usage: Int, isDown: Bool) {
137 | // get a non-unioned version of our controller input
138 | // (this is because Swift doesn't handle c structs with unions :/
139 | var controllerInput = unsafeControllerInputCast(input, 0)
140 |
141 | let endedDownVal = bool32(isDown ? 1 : 0)
142 |
143 | switch(usage) {
144 | case kHIDUsage_KeyboardA:
145 | controllerInput.memory.MoveLeft.EndedDown = endedDownVal
146 | break
147 | case kHIDUsage_KeyboardW:
148 | controllerInput.memory.MoveUp.EndedDown = endedDownVal
149 | break
150 | case kHIDUsage_KeyboardS:
151 | controllerInput.memory.MoveDown.EndedDown = endedDownVal
152 | break
153 | case kHIDUsage_KeyboardD:
154 | controllerInput.memory.MoveRight.EndedDown = endedDownVal
155 | break
156 | case kHIDUsage_KeyboardLeftArrow:
157 | controllerInput.memory.ActionLeft.EndedDown = endedDownVal
158 | break
159 | case kHIDUsage_KeyboardRightArrow:
160 | controllerInput.memory.ActionRight.EndedDown = endedDownVal
161 | break
162 | case kHIDUsage_KeyboardUpArrow:
163 | controllerInput.memory.ActionUp.EndedDown = endedDownVal
164 | break
165 | case kHIDUsage_KeyboardDownArrow:
166 | controllerInput.memory.ActionDown.EndedDown = endedDownVal
167 | break
168 | case kHIDUsage_KeyboardQ:
169 | controllerInput.memory.LeftShoulder.EndedDown = endedDownVal
170 | break
171 | case kHIDUsage_KeyboardE:
172 | controllerInput.memory.RightShoulder.EndedDown = endedDownVal
173 | break
174 | case kHIDUsage_KeyboardEscape:
175 | controllerInput.memory.Back.EndedDown = endedDownVal
176 | break
177 | case kHIDUsage_KeyboardSpacebar:
178 | controllerInput.memory.Start.EndedDown = endedDownVal
179 | break
180 |
181 | default:
182 | return
183 | }
184 | }
185 | }
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX/GameView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GameView.swift
3 | // Handmade Hero Swift Platform
4 | //
5 | // Created by Karl Kirch on 12/23/14.
6 | // Copyright (c) 2014 Handmade Hero. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 | import CoreVideo
11 |
12 | @objc class GameView: NSOpenGLView {
13 |
14 | // opengl defines
15 | // textureId that we'll use to store reference to our opengl texture
16 | var textureId: GLuint = GLuint()
17 | // pixel format attributes
18 | let pixelFormatAttrsBestCase: [NSOpenGLPixelFormatAttribute] = [
19 | UInt32(NSOpenGLPFADoubleBuffer),
20 | UInt32(NSOpenGLPFAAccelerated),
21 | UInt32(NSOpenGLPFADepthSize), UInt32(24),
22 | UInt32(0)
23 | ]
24 | let pixelFormatAttrsFallbackCase: [NSOpenGLPixelFormatAttribute] = [
25 | UInt32(NSOpenGLPFADepthSize), UInt32(24),
26 | UInt32(0)
27 | ]
28 | // list of vertices we'll use for defining our triangles
29 | let vertices: [GLfloat] = [
30 | -1, -1, 0,
31 | -1, 1, 0,
32 | 1, 1, 0,
33 | 1, -1, 0,
34 | ]
35 | // list of coordinates that we'll bind our texture to
36 | let texCoords: [GLfloat] = [
37 | 0, 1,
38 | 0, 0,
39 | 1, 0,
40 | 1, 1,
41 | ]
42 | // list of vertices to be used to draw triangles
43 | let triangleIndices: [GLushort] = [ 0, 1, 2, 0, 2, 3 ]
44 |
45 |
46 | // pointer to an uninitialized CVDisplayLinkRef
47 | var displayLink = UnsafeMutablePointer?>.alloc(1)
48 |
49 | let inputManager = InputManager()
50 |
51 | var platformLayer: PlatformLayer
52 |
53 | var targetFrameTime: real32 = 0
54 |
55 | required init?(coder: NSCoder) {
56 | platformLayer = PlatformLayer(anInputManager: inputManager)
57 | super.init(coder: coder)
58 | }
59 |
60 | override func awakeFromNib() {
61 | var pf = NSOpenGLPixelFormat(attributes: pixelFormatAttrsBestCase)
62 | if (pf == nil) {
63 | NSLog("Couldn't init opengl the way we wanted, using fallback")
64 | pf = NSOpenGLPixelFormat(attributes: pixelFormatAttrsFallbackCase)
65 | }
66 | if (pf == nil) {
67 | NSLog("Couldn't init opengl at all, sorry :(")
68 | abort()
69 | }
70 | let glContext = NSOpenGLContext(format: pf, shareContext: nil)
71 | self.pixelFormat = pf
72 | self.openGLContext = glContext
73 | }
74 |
75 | override func prepareOpenGL() {
76 | super.prepareOpenGL()
77 |
78 | // make current context for use
79 | openGLContext.makeCurrentContext()
80 |
81 | // lock context just in case something else is using it (shouldn't be though)
82 | CGLLockContext(openGLContext.CGLContextObj)
83 |
84 | // setup opengl defaults
85 | glDisable(GLenum(GL_DEPTH_TEST))
86 | glLoadIdentity()
87 |
88 | // setup viewport for opengl
89 | glViewport(0, 0, platformLayer.gameOffscreenBuffer.memory.Width, platformLayer.gameOffscreenBuffer.memory.Height);
90 |
91 | // set to use vsync (will default to 60hz in theory)
92 | var vsync = GLint(1)
93 | openGLContext.setValues(&vsync, forParameter:NSOpenGLContextParameter.GLCPSwapInterval)
94 |
95 | // I don't know what this does o_0
96 | glPixelStorei(GLenum(GL_UNPACK_ALIGNMENT), 1)
97 |
98 | // create texture for later so we can draw into it
99 | glGenTextures(1, &textureId)
100 | glBindTexture(GLenum(GL_TEXTURE_2D), textureId)
101 |
102 | // clear texture initially to get rid of junk from previous memory
103 | glTexImage2D(
104 | GLenum(GL_TEXTURE_2D),
105 | GLint(0),
106 | GLint(GL_RGBA),
107 | GLsizei(platformLayer.gameOffscreenBuffer.memory.Width), GLsizei(platformLayer.gameOffscreenBuffer.memory.Height),
108 | GLint(0),
109 | GLenum(GL_BGRA),
110 | GLenum(GL_UNSIGNED_INT_8_8_8_8_REV), UnsafePointer.null())
111 |
112 | // setup texture modes
113 | glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_NEAREST)
114 | glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAG_FILTER), GL_NEAREST)
115 | glTexEnvi(GLenum(GL_TEXTURE_ENV), GLenum(GL_TEXTURE_ENV_MODE), GL_REPLACE)
116 |
117 | // release lock on the opengl context
118 | CGLUnlockContext(openGLContext.CGLContextObj)
119 |
120 | // create displaylink and store in displayLink pointer
121 | CVDisplayLinkCreateWithActiveCGDisplays(displayLink)
122 |
123 | // get reference to displayLink memory now it's been created
124 | var displayLinkRef: CVDisplayLinkRef? = displayLink.memory?.takeUnretainedValue()
125 |
126 | // setup displaylink callback
127 | // need to create an UnsafeMutablePointer by using an unsafeBitCast
128 | let dlContext = unsafeBitCast(self, UnsafeMutablePointer.self)
129 | // call shim to get the displaylink callback (the shim calls getFrame when fired)
130 | CVDisplayLinkSetOutputCallback(displayLinkRef, getDisplayLinkCallback(), dlContext)
131 |
132 | // setup opengl for displaylink
133 | CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLinkRef, openGLContext.CGLContextObj, pixelFormat!.CGLPixelFormatObj)
134 |
135 | let cvtime = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(displayLinkRef)
136 | targetFrameTime = real32(cvtime.timeValue) / real32(cvtime.timeScale)
137 |
138 | // start the display link
139 | CVDisplayLinkStart(displayLinkRef)
140 |
141 | }
142 |
143 | // callback that our shim will call on cvdisplaylink fire
144 | func getFrame(time: UnsafePointer) {
145 |
146 | // lock the opengl context because the main thread might be drawing
147 | CGLLockContext(openGLContext.CGLContextObj)
148 |
149 | // make current for subsequent opengl calls
150 | openGLContext.makeCurrentContext()
151 |
152 | glClearColor(0x00, 0x00, 0x00, 0xFF)
153 | glClear(GLenum(GL_COLOR_BUFFER_BIT))
154 |
155 | glVertexPointer(GLint(3), GLenum(GL_FLOAT), GLsizei(0), vertices)
156 | glTexCoordPointer(GLint(2), GLenum(GL_FLOAT), GLsizei(0), texCoords)
157 |
158 | glEnableClientState(GLenum(GL_VERTEX_ARRAY))
159 | glEnableClientState(GLenum(GL_TEXTURE_COORD_ARRAY))
160 |
161 | glBindTexture(GLenum(GL_TEXTURE_2D), textureId)
162 |
163 | glEnable(GLenum(GL_TEXTURE_2D))
164 |
165 | // TODO: update input
166 |
167 | // TODO: call into platform layer to update the game
168 | platformLayer.platformGameUpdateAndRender(targetFrameTime)
169 |
170 | // TODO: update texture and draw to screen
171 | glTexSubImage2D(
172 | GLenum(GL_TEXTURE_2D),
173 | GLint(0),
174 | GLint(0),
175 | GLint(0),
176 | GLsizei(platformLayer.gameOffscreenBuffer.memory.Width), GLsizei(platformLayer.gameOffscreenBuffer.memory.Height),
177 | GLenum(GL_BGRA),
178 | GLenum(GL_UNSIGNED_INT_8_8_8_8_REV), platformLayer.gameOffscreenBuffer.memory.Memory)
179 |
180 | glColor4f(1, 1, 1, 1)
181 | glDrawElements(GLenum(GL_TRIANGLES), GLsizei(6), GLenum(GL_UNSIGNED_SHORT), triangleIndices)
182 | glDisable(GLenum(GL_TEXTURE_2D))
183 |
184 | glDisableClientState(GLenum(GL_VERTEX_ARRAY))
185 | glDisableClientState(GLenum(GL_TEXTURE_COORD_ARRAY))
186 |
187 | glFlush()
188 |
189 | // we're double buffered so need to flush to screen
190 | openGLContext.flushBuffer()
191 |
192 | CGLUnlockContext(openGLContext.CGLContextObj)
193 | }
194 |
195 | // resize the viewport when window size changes
196 | override func reshape() {
197 | // lock the opengl context because the displaylink might be drawing
198 | CGLLockContext(openGLContext.CGLContextObj)
199 |
200 | openGLContext.makeCurrentContext()
201 |
202 | // resize the viewport based on the view's size
203 | glDisable(GLenum(GL_DEPTH_TEST))
204 | glLoadIdentity()
205 | glViewport(0, 0, GLsizei(bounds.width), GLsizei(bounds.height))
206 |
207 | glClearColor(0x00, 0x00, 0x00, 0xFF)
208 | glClear(GLenum(GL_COLOR_BUFFER_BIT))
209 |
210 | // just draw whatever we have cached in the texture here, don't worry about updating the game
211 | glVertexPointer(GLint(3), GLenum(GL_FLOAT), GLsizei(0), vertices)
212 | glTexCoordPointer(GLint(2), GLenum(GL_FLOAT), GLsizei(0), texCoords)
213 |
214 | glEnableClientState(GLenum(GL_VERTEX_ARRAY))
215 | glEnableClientState(GLenum(GL_TEXTURE_COORD_ARRAY))
216 |
217 | glBindTexture(GLenum(GL_TEXTURE_2D), textureId)
218 |
219 | glEnable(GLenum(GL_TEXTURE_2D))
220 |
221 | glColor4f(1, 1, 1, 1)
222 | glDrawElements(GLenum(GL_TRIANGLES), GLsizei(6), GLenum(GL_UNSIGNED_SHORT), triangleIndices)
223 | glDisable(GLenum(GL_TEXTURE_2D))
224 |
225 | glDisableClientState(GLenum(GL_VERTEX_ARRAY))
226 | glDisableClientState(GLenum(GL_TEXTURE_COORD_ARRAY))
227 |
228 | // we're double buffered so need to flush to screen
229 | openGLContext.flushBuffer()
230 |
231 | CGLUnlockContext(openGLContext.CGLContextObj);
232 | }
233 |
234 |
235 | func setAppIsActive(active: Bool) {
236 | inputManager.shouldProcessInput = active
237 | }
238 |
239 | // accept first responder and ignore keyboard events because we handle them in the input manager
240 | func acceptsFirstResponder() -> Bool {
241 | return true;
242 | }
243 |
244 | override func keyDown(theEvent: NSEvent) {
245 | // noop
246 | }
247 |
248 | override func keyUp(theEvent: NSEvent) {
249 | // noop
250 | }
251 | }
252 |
253 |
--------------------------------------------------------------------------------
/Handmade Hero Dylib/Handmade Hero Dylib.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | CB0192781A6B05C1004638FA /* handmade_math.h in Headers */ = {isa = PBXBuildFile; fileRef = CB0192771A6B05C1004638FA /* handmade_math.h */; };
11 | CB1FBF661A5F361900B06069 /* handmade_random.h in Headers */ = {isa = PBXBuildFile; fileRef = CB1FBF631A5F361900B06069 /* handmade_random.h */; };
12 | CB1FBF681A5F361900B06069 /* handmade_tile.h in Headers */ = {isa = PBXBuildFile; fileRef = CB1FBF651A5F361900B06069 /* handmade_tile.h */; };
13 | CB469B691A50D9450000A950 /* handmade_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = CB469B661A50D9450000A950 /* handmade_platform.h */; };
14 | CB469B6A1A50D9450000A950 /* handmade.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB469B671A50D9450000A950 /* handmade.cpp */; };
15 | CB469B6B1A50D9450000A950 /* handmade.h in Headers */ = {isa = PBXBuildFile; fileRef = CB469B681A50D9450000A950 /* handmade.h */; };
16 | CBD97E151A54F237006CCBFB /* handmade_intrinsics.h in Headers */ = {isa = PBXBuildFile; fileRef = CBD97E141A54F237006CCBFB /* handmade_intrinsics.h */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXFileReference section */
20 | CB0192771A6B05C1004638FA /* handmade_math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = handmade_math.h; path = ../handmadeSrc/handmade_math.h; sourceTree = ""; };
21 | CB1FBF631A5F361900B06069 /* handmade_random.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = handmade_random.h; path = ../handmadeSrc/handmade_random.h; sourceTree = ""; };
22 | CB1FBF641A5F361900B06069 /* handmade_tile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = handmade_tile.cpp; path = ../handmadeSrc/handmade_tile.cpp; sourceTree = ""; };
23 | CB1FBF651A5F361900B06069 /* handmade_tile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = handmade_tile.h; path = ../handmadeSrc/handmade_tile.h; sourceTree = ""; };
24 | CB469B661A50D9450000A950 /* handmade_platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = handmade_platform.h; path = ../handmadeSrc/handmade_platform.h; sourceTree = ""; };
25 | CB469B671A50D9450000A950 /* handmade.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = handmade.cpp; path = ../handmadeSrc/handmade.cpp; sourceTree = ""; };
26 | CB469B681A50D9450000A950 /* handmade.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = handmade.h; path = ../handmadeSrc/handmade.h; sourceTree = ""; };
27 | CB60F04C1A4D38C400492AB5 /* libHandmade Hero Dylib.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = "libHandmade Hero Dylib.dylib"; sourceTree = BUILT_PRODUCTS_DIR; };
28 | CBD97E141A54F237006CCBFB /* handmade_intrinsics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = handmade_intrinsics.h; path = ../handmadeSrc/handmade_intrinsics.h; sourceTree = ""; };
29 | /* End PBXFileReference section */
30 |
31 | /* Begin PBXFrameworksBuildPhase section */
32 | CB60F0491A4D38C400492AB5 /* Frameworks */ = {
33 | isa = PBXFrameworksBuildPhase;
34 | buildActionMask = 2147483647;
35 | files = (
36 | );
37 | runOnlyForDeploymentPostprocessing = 0;
38 | };
39 | /* End PBXFrameworksBuildPhase section */
40 |
41 | /* Begin PBXGroup section */
42 | CB60F0431A4D38C400492AB5 = {
43 | isa = PBXGroup;
44 | children = (
45 | CB0192771A6B05C1004638FA /* handmade_math.h */,
46 | CB1FBF631A5F361900B06069 /* handmade_random.h */,
47 | CB1FBF641A5F361900B06069 /* handmade_tile.cpp */,
48 | CB1FBF651A5F361900B06069 /* handmade_tile.h */,
49 | CBD97E141A54F237006CCBFB /* handmade_intrinsics.h */,
50 | CB469B661A50D9450000A950 /* handmade_platform.h */,
51 | CB469B671A50D9450000A950 /* handmade.cpp */,
52 | CB469B681A50D9450000A950 /* handmade.h */,
53 | CB60F04D1A4D38C400492AB5 /* Products */,
54 | );
55 | sourceTree = "";
56 | };
57 | CB60F04D1A4D38C400492AB5 /* Products */ = {
58 | isa = PBXGroup;
59 | children = (
60 | CB60F04C1A4D38C400492AB5 /* libHandmade Hero Dylib.dylib */,
61 | );
62 | name = Products;
63 | sourceTree = "";
64 | };
65 | /* End PBXGroup section */
66 |
67 | /* Begin PBXHeadersBuildPhase section */
68 | CB60F04A1A4D38C400492AB5 /* Headers */ = {
69 | isa = PBXHeadersBuildPhase;
70 | buildActionMask = 2147483647;
71 | files = (
72 | CB0192781A6B05C1004638FA /* handmade_math.h in Headers */,
73 | CB1FBF681A5F361900B06069 /* handmade_tile.h in Headers */,
74 | CBD97E151A54F237006CCBFB /* handmade_intrinsics.h in Headers */,
75 | CB1FBF661A5F361900B06069 /* handmade_random.h in Headers */,
76 | CB469B6B1A50D9450000A950 /* handmade.h in Headers */,
77 | CB469B691A50D9450000A950 /* handmade_platform.h in Headers */,
78 | );
79 | runOnlyForDeploymentPostprocessing = 0;
80 | };
81 | /* End PBXHeadersBuildPhase section */
82 |
83 | /* Begin PBXNativeTarget section */
84 | CB60F04B1A4D38C400492AB5 /* Handmade Hero Dylib */ = {
85 | isa = PBXNativeTarget;
86 | buildConfigurationList = CB60F0501A4D38C400492AB5 /* Build configuration list for PBXNativeTarget "Handmade Hero Dylib" */;
87 | buildPhases = (
88 | CB60F0481A4D38C400492AB5 /* Sources */,
89 | CB60F0491A4D38C400492AB5 /* Frameworks */,
90 | CB60F04A1A4D38C400492AB5 /* Headers */,
91 | );
92 | buildRules = (
93 | );
94 | dependencies = (
95 | );
96 | name = "Handmade Hero Dylib";
97 | productName = "Handmade Hero Dylib";
98 | productReference = CB60F04C1A4D38C400492AB5 /* libHandmade Hero Dylib.dylib */;
99 | productType = "com.apple.product-type.library.dynamic";
100 | };
101 | /* End PBXNativeTarget section */
102 |
103 | /* Begin PBXProject section */
104 | CB60F0441A4D38C400492AB5 /* Project object */ = {
105 | isa = PBXProject;
106 | attributes = {
107 | LastUpgradeCheck = 0610;
108 | ORGANIZATIONNAME = "Handmade Hero";
109 | TargetAttributes = {
110 | CB60F04B1A4D38C400492AB5 = {
111 | CreatedOnToolsVersion = 6.1.1;
112 | };
113 | };
114 | };
115 | buildConfigurationList = CB60F0471A4D38C400492AB5 /* Build configuration list for PBXProject "Handmade Hero Dylib" */;
116 | compatibilityVersion = "Xcode 3.2";
117 | developmentRegion = English;
118 | hasScannedForEncodings = 0;
119 | knownRegions = (
120 | en,
121 | );
122 | mainGroup = CB60F0431A4D38C400492AB5;
123 | productRefGroup = CB60F04D1A4D38C400492AB5 /* Products */;
124 | projectDirPath = "";
125 | projectRoot = "";
126 | targets = (
127 | CB60F04B1A4D38C400492AB5 /* Handmade Hero Dylib */,
128 | );
129 | };
130 | /* End PBXProject section */
131 |
132 | /* Begin PBXSourcesBuildPhase section */
133 | CB60F0481A4D38C400492AB5 /* Sources */ = {
134 | isa = PBXSourcesBuildPhase;
135 | buildActionMask = 2147483647;
136 | files = (
137 | CB469B6A1A50D9450000A950 /* handmade.cpp in Sources */,
138 | );
139 | runOnlyForDeploymentPostprocessing = 0;
140 | };
141 | /* End PBXSourcesBuildPhase section */
142 |
143 | /* Begin XCBuildConfiguration section */
144 | CB60F04E1A4D38C400492AB5 /* Debug */ = {
145 | isa = XCBuildConfiguration;
146 | buildSettings = {
147 | ALWAYS_SEARCH_USER_PATHS = NO;
148 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
149 | CLANG_CXX_LIBRARY = "libc++";
150 | CLANG_ENABLE_MODULES = YES;
151 | CLANG_ENABLE_OBJC_ARC = YES;
152 | CLANG_WARN_BOOL_CONVERSION = YES;
153 | CLANG_WARN_CONSTANT_CONVERSION = YES;
154 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
155 | CLANG_WARN_EMPTY_BODY = YES;
156 | CLANG_WARN_ENUM_CONVERSION = YES;
157 | CLANG_WARN_INT_CONVERSION = YES;
158 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
159 | CLANG_WARN_UNREACHABLE_CODE = YES;
160 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
161 | COPY_PHASE_STRIP = NO;
162 | ENABLE_STRICT_OBJC_MSGSEND = YES;
163 | GCC_C_LANGUAGE_STANDARD = gnu99;
164 | GCC_DYNAMIC_NO_PIC = NO;
165 | GCC_OPTIMIZATION_LEVEL = 0;
166 | GCC_PREPROCESSOR_DEFINITIONS = (
167 | "DEBUG=1",
168 | "$(inherited)",
169 | );
170 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
171 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
172 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
173 | GCC_WARN_UNDECLARED_SELECTOR = YES;
174 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
175 | GCC_WARN_UNUSED_FUNCTION = YES;
176 | GCC_WARN_UNUSED_VARIABLE = YES;
177 | MACOSX_DEPLOYMENT_TARGET = 10.9;
178 | MTL_ENABLE_DEBUG_INFO = YES;
179 | ONLY_ACTIVE_ARCH = YES;
180 | OTHER_CFLAGS = "-Dsize_t=__darwin_size_t";
181 | SDKROOT = macosx;
182 | };
183 | name = Debug;
184 | };
185 | CB60F04F1A4D38C400492AB5 /* Release */ = {
186 | isa = XCBuildConfiguration;
187 | buildSettings = {
188 | ALWAYS_SEARCH_USER_PATHS = NO;
189 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
190 | CLANG_CXX_LIBRARY = "libc++";
191 | CLANG_ENABLE_MODULES = YES;
192 | CLANG_ENABLE_OBJC_ARC = YES;
193 | CLANG_WARN_BOOL_CONVERSION = YES;
194 | CLANG_WARN_CONSTANT_CONVERSION = YES;
195 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
196 | CLANG_WARN_EMPTY_BODY = YES;
197 | CLANG_WARN_ENUM_CONVERSION = YES;
198 | CLANG_WARN_INT_CONVERSION = YES;
199 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
200 | CLANG_WARN_UNREACHABLE_CODE = YES;
201 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
202 | COPY_PHASE_STRIP = YES;
203 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
204 | ENABLE_NS_ASSERTIONS = NO;
205 | ENABLE_STRICT_OBJC_MSGSEND = YES;
206 | GCC_C_LANGUAGE_STANDARD = gnu99;
207 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
208 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
209 | GCC_WARN_UNDECLARED_SELECTOR = YES;
210 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
211 | GCC_WARN_UNUSED_FUNCTION = YES;
212 | GCC_WARN_UNUSED_VARIABLE = YES;
213 | MACOSX_DEPLOYMENT_TARGET = 10.9;
214 | MTL_ENABLE_DEBUG_INFO = NO;
215 | OTHER_CFLAGS = "-Dsize_t=__darwin_size_t";
216 | SDKROOT = macosx;
217 | };
218 | name = Release;
219 | };
220 | CB60F0511A4D38C400492AB5 /* Debug */ = {
221 | isa = XCBuildConfiguration;
222 | buildSettings = {
223 | DYLIB_COMPATIBILITY_VERSION = 1;
224 | DYLIB_CURRENT_VERSION = 1;
225 | EXECUTABLE_PREFIX = lib;
226 | "GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = (
227 | "HANDMADE_INTERNAL=1",
228 | "HANDMADE_SLOW=1",
229 | "$(inherited)",
230 | );
231 | PRODUCT_NAME = "$(TARGET_NAME)";
232 | };
233 | name = Debug;
234 | };
235 | CB60F0521A4D38C400492AB5 /* Release */ = {
236 | isa = XCBuildConfiguration;
237 | buildSettings = {
238 | DYLIB_COMPATIBILITY_VERSION = 1;
239 | DYLIB_CURRENT_VERSION = 1;
240 | EXECUTABLE_PREFIX = lib;
241 | GCC_OPTIMIZATION_LEVEL = s;
242 | "GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = "HANDMADE_INTERNAL=1";
243 | PRODUCT_NAME = "$(TARGET_NAME)";
244 | };
245 | name = Release;
246 | };
247 | /* End XCBuildConfiguration section */
248 |
249 | /* Begin XCConfigurationList section */
250 | CB60F0471A4D38C400492AB5 /* Build configuration list for PBXProject "Handmade Hero Dylib" */ = {
251 | isa = XCConfigurationList;
252 | buildConfigurations = (
253 | CB60F04E1A4D38C400492AB5 /* Debug */,
254 | CB60F04F1A4D38C400492AB5 /* Release */,
255 | );
256 | defaultConfigurationIsVisible = 0;
257 | defaultConfigurationName = Release;
258 | };
259 | CB60F0501A4D38C400492AB5 /* Build configuration list for PBXNativeTarget "Handmade Hero Dylib" */ = {
260 | isa = XCConfigurationList;
261 | buildConfigurations = (
262 | CB60F0511A4D38C400492AB5 /* Debug */,
263 | CB60F0521A4D38C400492AB5 /* Release */,
264 | );
265 | defaultConfigurationIsVisible = 0;
266 | defaultConfigurationName = Release;
267 | };
268 | /* End XCConfigurationList section */
269 | };
270 | rootObject = CB60F0441A4D38C400492AB5 /* Project object */;
271 | }
272 |
--------------------------------------------------------------------------------
/Handmade Hero OSX/Handmade Hero OSX.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | CB1FBFA61A5F395D00B06069 /* test_background.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF6D1A5F391E00B06069 /* test_background.bmp */; };
11 | CB1FBFA71A5F395D00B06069 /* test_hero_back_cape.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF6E1A5F391E00B06069 /* test_hero_back_cape.bmp */; };
12 | CB1FBFA81A5F395D00B06069 /* test_hero_back_head.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF6F1A5F391E00B06069 /* test_hero_back_head.bmp */; };
13 | CB1FBFA91A5F395D00B06069 /* test_hero_back_torso.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF701A5F391E00B06069 /* test_hero_back_torso.bmp */; };
14 | CB1FBFAA1A5F395D00B06069 /* test_hero_front_cape.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF711A5F391E00B06069 /* test_hero_front_cape.bmp */; };
15 | CB1FBFAB1A5F395D00B06069 /* test_hero_front_head.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF721A5F391E00B06069 /* test_hero_front_head.bmp */; };
16 | CB1FBFAC1A5F395D00B06069 /* test_hero_front_torso.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF731A5F391E00B06069 /* test_hero_front_torso.bmp */; };
17 | CB1FBFAD1A5F395D00B06069 /* test_hero_left_cape.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF741A5F391E00B06069 /* test_hero_left_cape.bmp */; };
18 | CB1FBFAE1A5F395D00B06069 /* test_hero_left_head.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF751A5F391E00B06069 /* test_hero_left_head.bmp */; };
19 | CB1FBFAF1A5F395D00B06069 /* test_hero_left_torso.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF761A5F391E00B06069 /* test_hero_left_torso.bmp */; };
20 | CB1FBFB01A5F395D00B06069 /* test_hero_right_cape.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF771A5F391E00B06069 /* test_hero_right_cape.bmp */; };
21 | CB1FBFB11A5F395D00B06069 /* test_hero_right_head.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF781A5F391E00B06069 /* test_hero_right_head.bmp */; };
22 | CB1FBFB21A5F395D00B06069 /* test_hero_right_torso.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF791A5F391E00B06069 /* test_hero_right_torso.bmp */; };
23 | CB1FBFB31A5F395D00B06069 /* test_hero_shadow.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF7A1A5F391E00B06069 /* test_hero_shadow.bmp */; };
24 | CB1FBFB41A5F395D00B06069 /* test_scene_layer_00.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF7B1A5F391E00B06069 /* test_scene_layer_00.bmp */; };
25 | CB1FBFB51A5F395D00B06069 /* test_scene_layer_01.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF7C1A5F391E00B06069 /* test_scene_layer_01.bmp */; };
26 | CB1FBFB61A5F395D00B06069 /* test_scene_layer_02.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF7D1A5F391E00B06069 /* test_scene_layer_02.bmp */; };
27 | CB1FBFB71A5F395D00B06069 /* test_scene_layer_03.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF7E1A5F391E00B06069 /* test_scene_layer_03.bmp */; };
28 | CB1FBFB81A5F395D00B06069 /* test_scene_layer_04.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB1FBF7F1A5F391E00B06069 /* test_scene_layer_04.bmp */; };
29 | CB1FBFBA1A5F39A000B06069 /* libHandmade Hero Dylib.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB469B651A50D8D90000A950 /* libHandmade Hero Dylib.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
30 | CB469B461A50D8A40000A950 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB469B451A50D8A40000A950 /* AppDelegate.swift */; };
31 | CB469B481A50D8A40000A950 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CB469B471A50D8A40000A950 /* Images.xcassets */; };
32 | CB469B4B1A50D8A40000A950 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CB469B491A50D8A40000A950 /* MainMenu.xib */; };
33 | CB469B571A50D8A40000A950 /* Handmade_Hero_OSXTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB469B561A50D8A40000A950 /* Handmade_Hero_OSXTests.swift */; };
34 | CB469B741A50D9DE0000A950 /* GameCodeLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB469B6C1A50D9DE0000A950 /* GameCodeLoader.swift */; };
35 | CB469B751A50D9DE0000A950 /* GameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB469B6D1A50D9DE0000A950 /* GameView.swift */; };
36 | CB469B761A50D9DE0000A950 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB469B6F1A50D9DE0000A950 /* Helpers.swift */; };
37 | CB469B771A50D9DE0000A950 /* InputManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB469B701A50D9DE0000A950 /* InputManager.swift */; };
38 | CB469B781A50D9DE0000A950 /* ObjCShim.m in Sources */ = {isa = PBXBuildFile; fileRef = CB469B721A50D9DE0000A950 /* ObjCShim.m */; };
39 | CB469B791A50D9DE0000A950 /* PlatformLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB469B731A50D9DE0000A950 /* PlatformLayer.swift */; };
40 | CB469B7B1A50D9F90000A950 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB469B7A1A50D9F90000A950 /* OpenGL.framework */; };
41 | CB469B7D1A50DA000000A950 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB469B7C1A50DA000000A950 /* CoreVideo.framework */; };
42 | CB469B7F1A50DA090000A950 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB469B7E1A50DA090000A950 /* IOKit.framework */; };
43 | CBD97E171A54F662006CCBFB /* SoundManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD97E161A54F662006CCBFB /* SoundManager.swift */; };
44 | CBD97E191A54FB92006CCBFB /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CBD97E181A54FB92006CCBFB /* CoreAudio.framework */; };
45 | /* End PBXBuildFile section */
46 |
47 | /* Begin PBXContainerItemProxy section */
48 | CB469B511A50D8A40000A950 /* PBXContainerItemProxy */ = {
49 | isa = PBXContainerItemProxy;
50 | containerPortal = CB469B381A50D8A40000A950 /* Project object */;
51 | proxyType = 1;
52 | remoteGlobalIDString = CB469B3F1A50D8A40000A950;
53 | remoteInfo = "Handmade Hero OSX";
54 | };
55 | CB469B641A50D8D90000A950 /* PBXContainerItemProxy */ = {
56 | isa = PBXContainerItemProxy;
57 | containerPortal = CB469B601A50D8D90000A950 /* Handmade Hero Dylib.xcodeproj */;
58 | proxyType = 2;
59 | remoteGlobalIDString = CB60F04C1A4D38C400492AB5;
60 | remoteInfo = "Handmade Hero Dylib";
61 | };
62 | /* End PBXContainerItemProxy section */
63 |
64 | /* Begin PBXCopyFilesBuildPhase section */
65 | CB1FBFB91A5F399A00B06069 /* CopyFiles */ = {
66 | isa = PBXCopyFilesBuildPhase;
67 | buildActionMask = 2147483647;
68 | dstPath = "";
69 | dstSubfolderSpec = 10;
70 | files = (
71 | CB1FBFBA1A5F39A000B06069 /* libHandmade Hero Dylib.dylib in CopyFiles */,
72 | );
73 | runOnlyForDeploymentPostprocessing = 0;
74 | };
75 | CB469B841A50DAFE0000A950 /* CopyFiles */ = {
76 | isa = PBXCopyFilesBuildPhase;
77 | buildActionMask = 2147483647;
78 | dstPath = test;
79 | dstSubfolderSpec = 7;
80 | files = (
81 | CB1FBFA61A5F395D00B06069 /* test_background.bmp in CopyFiles */,
82 | CB1FBFA71A5F395D00B06069 /* test_hero_back_cape.bmp in CopyFiles */,
83 | CB1FBFA81A5F395D00B06069 /* test_hero_back_head.bmp in CopyFiles */,
84 | CB1FBFA91A5F395D00B06069 /* test_hero_back_torso.bmp in CopyFiles */,
85 | CB1FBFAA1A5F395D00B06069 /* test_hero_front_cape.bmp in CopyFiles */,
86 | CB1FBFAB1A5F395D00B06069 /* test_hero_front_head.bmp in CopyFiles */,
87 | CB1FBFAC1A5F395D00B06069 /* test_hero_front_torso.bmp in CopyFiles */,
88 | CB1FBFAD1A5F395D00B06069 /* test_hero_left_cape.bmp in CopyFiles */,
89 | CB1FBFAE1A5F395D00B06069 /* test_hero_left_head.bmp in CopyFiles */,
90 | CB1FBFAF1A5F395D00B06069 /* test_hero_left_torso.bmp in CopyFiles */,
91 | CB1FBFB01A5F395D00B06069 /* test_hero_right_cape.bmp in CopyFiles */,
92 | CB1FBFB11A5F395D00B06069 /* test_hero_right_head.bmp in CopyFiles */,
93 | CB1FBFB21A5F395D00B06069 /* test_hero_right_torso.bmp in CopyFiles */,
94 | CB1FBFB31A5F395D00B06069 /* test_hero_shadow.bmp in CopyFiles */,
95 | CB1FBFB41A5F395D00B06069 /* test_scene_layer_00.bmp in CopyFiles */,
96 | CB1FBFB51A5F395D00B06069 /* test_scene_layer_01.bmp in CopyFiles */,
97 | CB1FBFB61A5F395D00B06069 /* test_scene_layer_02.bmp in CopyFiles */,
98 | CB1FBFB71A5F395D00B06069 /* test_scene_layer_03.bmp in CopyFiles */,
99 | CB1FBFB81A5F395D00B06069 /* test_scene_layer_04.bmp in CopyFiles */,
100 | );
101 | runOnlyForDeploymentPostprocessing = 0;
102 | };
103 | /* End PBXCopyFilesBuildPhase section */
104 |
105 | /* Begin PBXFileReference section */
106 | CB1FBF6D1A5F391E00B06069 /* test_background.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_background.bmp; sourceTree = ""; };
107 | CB1FBF6E1A5F391E00B06069 /* test_hero_back_cape.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_hero_back_cape.bmp; sourceTree = ""; };
108 | CB1FBF6F1A5F391E00B06069 /* test_hero_back_head.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_hero_back_head.bmp; sourceTree = ""; };
109 | CB1FBF701A5F391E00B06069 /* test_hero_back_torso.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_hero_back_torso.bmp; sourceTree = ""; };
110 | CB1FBF711A5F391E00B06069 /* test_hero_front_cape.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_hero_front_cape.bmp; sourceTree = ""; };
111 | CB1FBF721A5F391E00B06069 /* test_hero_front_head.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_hero_front_head.bmp; sourceTree = ""; };
112 | CB1FBF731A5F391E00B06069 /* test_hero_front_torso.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_hero_front_torso.bmp; sourceTree = ""; };
113 | CB1FBF741A5F391E00B06069 /* test_hero_left_cape.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_hero_left_cape.bmp; sourceTree = ""; };
114 | CB1FBF751A5F391E00B06069 /* test_hero_left_head.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_hero_left_head.bmp; sourceTree = ""; };
115 | CB1FBF761A5F391E00B06069 /* test_hero_left_torso.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_hero_left_torso.bmp; sourceTree = ""; };
116 | CB1FBF771A5F391E00B06069 /* test_hero_right_cape.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_hero_right_cape.bmp; sourceTree = ""; };
117 | CB1FBF781A5F391E00B06069 /* test_hero_right_head.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_hero_right_head.bmp; sourceTree = ""; };
118 | CB1FBF791A5F391E00B06069 /* test_hero_right_torso.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_hero_right_torso.bmp; sourceTree = ""; };
119 | CB1FBF7A1A5F391E00B06069 /* test_hero_shadow.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_hero_shadow.bmp; sourceTree = ""; };
120 | CB1FBF7B1A5F391E00B06069 /* test_scene_layer_00.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_scene_layer_00.bmp; sourceTree = ""; };
121 | CB1FBF7C1A5F391E00B06069 /* test_scene_layer_01.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_scene_layer_01.bmp; sourceTree = ""; };
122 | CB1FBF7D1A5F391E00B06069 /* test_scene_layer_02.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_scene_layer_02.bmp; sourceTree = ""; };
123 | CB1FBF7E1A5F391E00B06069 /* test_scene_layer_03.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_scene_layer_03.bmp; sourceTree = ""; };
124 | CB1FBF7F1A5F391E00B06069 /* test_scene_layer_04.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = test_scene_layer_04.bmp; sourceTree = ""; };
125 | CB469B401A50D8A40000A950 /* Handmade Hero OSX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Handmade Hero OSX.app"; sourceTree = BUILT_PRODUCTS_DIR; };
126 | CB469B441A50D8A40000A950 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
127 | CB469B451A50D8A40000A950 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
128 | CB469B471A50D8A40000A950 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
129 | CB469B4A1A50D8A40000A950 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; };
130 | CB469B501A50D8A40000A950 /* Handmade Hero OSXTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Handmade Hero OSXTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
131 | CB469B551A50D8A40000A950 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
132 | CB469B561A50D8A40000A950 /* Handmade_Hero_OSXTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Handmade_Hero_OSXTests.swift; sourceTree = ""; };
133 | CB469B601A50D8D90000A950 /* Handmade Hero Dylib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "Handmade Hero Dylib.xcodeproj"; path = "../Handmade Hero Dylib/Handmade Hero Dylib.xcodeproj"; sourceTree = ""; };
134 | CB469B6C1A50D9DE0000A950 /* GameCodeLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameCodeLoader.swift; sourceTree = ""; };
135 | CB469B6D1A50D9DE0000A950 /* GameView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameView.swift; sourceTree = ""; };
136 | CB469B6E1A50D9DE0000A950 /* Handmade Hero OSX-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Handmade Hero OSX-Bridging-Header.h"; sourceTree = ""; };
137 | CB469B6F1A50D9DE0000A950 /* Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = ""; };
138 | CB469B701A50D9DE0000A950 /* InputManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputManager.swift; sourceTree = ""; };
139 | CB469B711A50D9DE0000A950 /* ObjCShim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjCShim.h; sourceTree = ""; };
140 | CB469B721A50D9DE0000A950 /* ObjCShim.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCShim.m; sourceTree = ""; };
141 | CB469B731A50D9DE0000A950 /* PlatformLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlatformLayer.swift; sourceTree = ""; };
142 | CB469B7A1A50D9F90000A950 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
143 | CB469B7C1A50DA000000A950 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; };
144 | CB469B7E1A50DA090000A950 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
145 | CB469B821A50DA880000A950 /* handmade_platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = handmade_platform.h; path = ../../handmadeSrc/handmade_platform.h; sourceTree = ""; };
146 | CBD97E161A54F662006CCBFB /* SoundManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SoundManager.swift; sourceTree = ""; };
147 | CBD97E181A54FB92006CCBFB /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
148 | /* End PBXFileReference section */
149 |
150 | /* Begin PBXFrameworksBuildPhase section */
151 | CB469B3D1A50D8A40000A950 /* Frameworks */ = {
152 | isa = PBXFrameworksBuildPhase;
153 | buildActionMask = 2147483647;
154 | files = (
155 | CBD97E191A54FB92006CCBFB /* CoreAudio.framework in Frameworks */,
156 | CB469B7F1A50DA090000A950 /* IOKit.framework in Frameworks */,
157 | CB469B7D1A50DA000000A950 /* CoreVideo.framework in Frameworks */,
158 | CB469B7B1A50D9F90000A950 /* OpenGL.framework in Frameworks */,
159 | );
160 | runOnlyForDeploymentPostprocessing = 0;
161 | };
162 | CB469B4D1A50D8A40000A950 /* Frameworks */ = {
163 | isa = PBXFrameworksBuildPhase;
164 | buildActionMask = 2147483647;
165 | files = (
166 | );
167 | runOnlyForDeploymentPostprocessing = 0;
168 | };
169 | /* End PBXFrameworksBuildPhase section */
170 |
171 | /* Begin PBXGroup section */
172 | CB1FBF6A1A5F390F00B06069 /* Handmade Hero Assets */ = {
173 | isa = PBXGroup;
174 | children = (
175 | CB1FBF6C1A5F391E00B06069 /* test */,
176 | );
177 | name = "Handmade Hero Assets";
178 | sourceTree = "";
179 | };
180 | CB1FBF6C1A5F391E00B06069 /* test */ = {
181 | isa = PBXGroup;
182 | children = (
183 | CB1FBF6D1A5F391E00B06069 /* test_background.bmp */,
184 | CB1FBF6E1A5F391E00B06069 /* test_hero_back_cape.bmp */,
185 | CB1FBF6F1A5F391E00B06069 /* test_hero_back_head.bmp */,
186 | CB1FBF701A5F391E00B06069 /* test_hero_back_torso.bmp */,
187 | CB1FBF711A5F391E00B06069 /* test_hero_front_cape.bmp */,
188 | CB1FBF721A5F391E00B06069 /* test_hero_front_head.bmp */,
189 | CB1FBF731A5F391E00B06069 /* test_hero_front_torso.bmp */,
190 | CB1FBF741A5F391E00B06069 /* test_hero_left_cape.bmp */,
191 | CB1FBF751A5F391E00B06069 /* test_hero_left_head.bmp */,
192 | CB1FBF761A5F391E00B06069 /* test_hero_left_torso.bmp */,
193 | CB1FBF771A5F391E00B06069 /* test_hero_right_cape.bmp */,
194 | CB1FBF781A5F391E00B06069 /* test_hero_right_head.bmp */,
195 | CB1FBF791A5F391E00B06069 /* test_hero_right_torso.bmp */,
196 | CB1FBF7A1A5F391E00B06069 /* test_hero_shadow.bmp */,
197 | CB1FBF7B1A5F391E00B06069 /* test_scene_layer_00.bmp */,
198 | CB1FBF7C1A5F391E00B06069 /* test_scene_layer_01.bmp */,
199 | CB1FBF7D1A5F391E00B06069 /* test_scene_layer_02.bmp */,
200 | CB1FBF7E1A5F391E00B06069 /* test_scene_layer_03.bmp */,
201 | CB1FBF7F1A5F391E00B06069 /* test_scene_layer_04.bmp */,
202 | );
203 | name = test;
204 | path = ../../handmadeAssets/test;
205 | sourceTree = "";
206 | };
207 | CB469B371A50D8A40000A950 = {
208 | isa = PBXGroup;
209 | children = (
210 | CB469B601A50D8D90000A950 /* Handmade Hero Dylib.xcodeproj */,
211 | CB469B421A50D8A40000A950 /* Handmade Hero OSX */,
212 | CB469B531A50D8A40000A950 /* Handmade Hero OSXTests */,
213 | CB469B411A50D8A40000A950 /* Products */,
214 | CBD97E181A54FB92006CCBFB /* CoreAudio.framework */,
215 | CB469B7E1A50DA090000A950 /* IOKit.framework */,
216 | CB469B7C1A50DA000000A950 /* CoreVideo.framework */,
217 | CB469B7A1A50D9F90000A950 /* OpenGL.framework */,
218 | );
219 | sourceTree = "";
220 | };
221 | CB469B411A50D8A40000A950 /* Products */ = {
222 | isa = PBXGroup;
223 | children = (
224 | CB469B401A50D8A40000A950 /* Handmade Hero OSX.app */,
225 | CB469B501A50D8A40000A950 /* Handmade Hero OSXTests.xctest */,
226 | );
227 | name = Products;
228 | sourceTree = "";
229 | };
230 | CB469B421A50D8A40000A950 /* Handmade Hero OSX */ = {
231 | isa = PBXGroup;
232 | children = (
233 | CB1FBF6A1A5F390F00B06069 /* Handmade Hero Assets */,
234 | CB469B831A50DA8C0000A950 /* Handmade Hero Headers */,
235 | CB469B451A50D8A40000A950 /* AppDelegate.swift */,
236 | CB469B6C1A50D9DE0000A950 /* GameCodeLoader.swift */,
237 | CB469B6D1A50D9DE0000A950 /* GameView.swift */,
238 | CB469B6E1A50D9DE0000A950 /* Handmade Hero OSX-Bridging-Header.h */,
239 | CB469B6F1A50D9DE0000A950 /* Helpers.swift */,
240 | CB469B701A50D9DE0000A950 /* InputManager.swift */,
241 | CB469B711A50D9DE0000A950 /* ObjCShim.h */,
242 | CB469B721A50D9DE0000A950 /* ObjCShim.m */,
243 | CB469B731A50D9DE0000A950 /* PlatformLayer.swift */,
244 | CBD97E161A54F662006CCBFB /* SoundManager.swift */,
245 | CB469B471A50D8A40000A950 /* Images.xcassets */,
246 | CB469B491A50D8A40000A950 /* MainMenu.xib */,
247 | CB469B431A50D8A40000A950 /* Supporting Files */,
248 | );
249 | path = "Handmade Hero OSX";
250 | sourceTree = "";
251 | };
252 | CB469B431A50D8A40000A950 /* Supporting Files */ = {
253 | isa = PBXGroup;
254 | children = (
255 | CB469B441A50D8A40000A950 /* Info.plist */,
256 | );
257 | name = "Supporting Files";
258 | sourceTree = "";
259 | };
260 | CB469B531A50D8A40000A950 /* Handmade Hero OSXTests */ = {
261 | isa = PBXGroup;
262 | children = (
263 | CB469B561A50D8A40000A950 /* Handmade_Hero_OSXTests.swift */,
264 | CB469B541A50D8A40000A950 /* Supporting Files */,
265 | );
266 | path = "Handmade Hero OSXTests";
267 | sourceTree = "";
268 | };
269 | CB469B541A50D8A40000A950 /* Supporting Files */ = {
270 | isa = PBXGroup;
271 | children = (
272 | CB469B551A50D8A40000A950 /* Info.plist */,
273 | );
274 | name = "Supporting Files";
275 | sourceTree = "";
276 | };
277 | CB469B611A50D8D90000A950 /* Products */ = {
278 | isa = PBXGroup;
279 | children = (
280 | CB469B651A50D8D90000A950 /* libHandmade Hero Dylib.dylib */,
281 | );
282 | name = Products;
283 | sourceTree = "";
284 | };
285 | CB469B831A50DA8C0000A950 /* Handmade Hero Headers */ = {
286 | isa = PBXGroup;
287 | children = (
288 | CB469B821A50DA880000A950 /* handmade_platform.h */,
289 | );
290 | name = "Handmade Hero Headers";
291 | sourceTree = "";
292 | };
293 | /* End PBXGroup section */
294 |
295 | /* Begin PBXNativeTarget section */
296 | CB469B3F1A50D8A40000A950 /* Handmade Hero OSX */ = {
297 | isa = PBXNativeTarget;
298 | buildConfigurationList = CB469B5A1A50D8A40000A950 /* Build configuration list for PBXNativeTarget "Handmade Hero OSX" */;
299 | buildPhases = (
300 | CB469B3C1A50D8A40000A950 /* Sources */,
301 | CB469B3D1A50D8A40000A950 /* Frameworks */,
302 | CB469B3E1A50D8A40000A950 /* Resources */,
303 | CB469B841A50DAFE0000A950 /* CopyFiles */,
304 | CB1FBFB91A5F399A00B06069 /* CopyFiles */,
305 | );
306 | buildRules = (
307 | );
308 | dependencies = (
309 | );
310 | name = "Handmade Hero OSX";
311 | productName = "Handmade Hero OSX";
312 | productReference = CB469B401A50D8A40000A950 /* Handmade Hero OSX.app */;
313 | productType = "com.apple.product-type.application";
314 | };
315 | CB469B4F1A50D8A40000A950 /* Handmade Hero OSXTests */ = {
316 | isa = PBXNativeTarget;
317 | buildConfigurationList = CB469B5D1A50D8A40000A950 /* Build configuration list for PBXNativeTarget "Handmade Hero OSXTests" */;
318 | buildPhases = (
319 | CB469B4C1A50D8A40000A950 /* Sources */,
320 | CB469B4D1A50D8A40000A950 /* Frameworks */,
321 | CB469B4E1A50D8A40000A950 /* Resources */,
322 | );
323 | buildRules = (
324 | );
325 | dependencies = (
326 | CB469B521A50D8A40000A950 /* PBXTargetDependency */,
327 | );
328 | name = "Handmade Hero OSXTests";
329 | productName = "Handmade Hero OSXTests";
330 | productReference = CB469B501A50D8A40000A950 /* Handmade Hero OSXTests.xctest */;
331 | productType = "com.apple.product-type.bundle.unit-test";
332 | };
333 | /* End PBXNativeTarget section */
334 |
335 | /* Begin PBXProject section */
336 | CB469B381A50D8A40000A950 /* Project object */ = {
337 | isa = PBXProject;
338 | attributes = {
339 | LastUpgradeCheck = 0610;
340 | ORGANIZATIONNAME = "Handmade Hero";
341 | TargetAttributes = {
342 | CB469B3F1A50D8A40000A950 = {
343 | CreatedOnToolsVersion = 6.1.1;
344 | };
345 | CB469B4F1A50D8A40000A950 = {
346 | CreatedOnToolsVersion = 6.1.1;
347 | TestTargetID = CB469B3F1A50D8A40000A950;
348 | };
349 | };
350 | };
351 | buildConfigurationList = CB469B3B1A50D8A40000A950 /* Build configuration list for PBXProject "Handmade Hero OSX" */;
352 | compatibilityVersion = "Xcode 3.2";
353 | developmentRegion = English;
354 | hasScannedForEncodings = 0;
355 | knownRegions = (
356 | en,
357 | Base,
358 | );
359 | mainGroup = CB469B371A50D8A40000A950;
360 | productRefGroup = CB469B411A50D8A40000A950 /* Products */;
361 | projectDirPath = "";
362 | projectReferences = (
363 | {
364 | ProductGroup = CB469B611A50D8D90000A950 /* Products */;
365 | ProjectRef = CB469B601A50D8D90000A950 /* Handmade Hero Dylib.xcodeproj */;
366 | },
367 | );
368 | projectRoot = "";
369 | targets = (
370 | CB469B3F1A50D8A40000A950 /* Handmade Hero OSX */,
371 | CB469B4F1A50D8A40000A950 /* Handmade Hero OSXTests */,
372 | );
373 | };
374 | /* End PBXProject section */
375 |
376 | /* Begin PBXReferenceProxy section */
377 | CB469B651A50D8D90000A950 /* libHandmade Hero Dylib.dylib */ = {
378 | isa = PBXReferenceProxy;
379 | fileType = "compiled.mach-o.dylib";
380 | path = "libHandmade Hero Dylib.dylib";
381 | remoteRef = CB469B641A50D8D90000A950 /* PBXContainerItemProxy */;
382 | sourceTree = BUILT_PRODUCTS_DIR;
383 | };
384 | /* End PBXReferenceProxy section */
385 |
386 | /* Begin PBXResourcesBuildPhase section */
387 | CB469B3E1A50D8A40000A950 /* Resources */ = {
388 | isa = PBXResourcesBuildPhase;
389 | buildActionMask = 2147483647;
390 | files = (
391 | CB469B481A50D8A40000A950 /* Images.xcassets in Resources */,
392 | CB469B4B1A50D8A40000A950 /* MainMenu.xib in Resources */,
393 | );
394 | runOnlyForDeploymentPostprocessing = 0;
395 | };
396 | CB469B4E1A50D8A40000A950 /* Resources */ = {
397 | isa = PBXResourcesBuildPhase;
398 | buildActionMask = 2147483647;
399 | files = (
400 | );
401 | runOnlyForDeploymentPostprocessing = 0;
402 | };
403 | /* End PBXResourcesBuildPhase section */
404 |
405 | /* Begin PBXSourcesBuildPhase section */
406 | CB469B3C1A50D8A40000A950 /* Sources */ = {
407 | isa = PBXSourcesBuildPhase;
408 | buildActionMask = 2147483647;
409 | files = (
410 | CB469B771A50D9DE0000A950 /* InputManager.swift in Sources */,
411 | CBD97E171A54F662006CCBFB /* SoundManager.swift in Sources */,
412 | CB469B461A50D8A40000A950 /* AppDelegate.swift in Sources */,
413 | CB469B781A50D9DE0000A950 /* ObjCShim.m in Sources */,
414 | CB469B751A50D9DE0000A950 /* GameView.swift in Sources */,
415 | CB469B741A50D9DE0000A950 /* GameCodeLoader.swift in Sources */,
416 | CB469B761A50D9DE0000A950 /* Helpers.swift in Sources */,
417 | CB469B791A50D9DE0000A950 /* PlatformLayer.swift in Sources */,
418 | );
419 | runOnlyForDeploymentPostprocessing = 0;
420 | };
421 | CB469B4C1A50D8A40000A950 /* Sources */ = {
422 | isa = PBXSourcesBuildPhase;
423 | buildActionMask = 2147483647;
424 | files = (
425 | CB469B571A50D8A40000A950 /* Handmade_Hero_OSXTests.swift in Sources */,
426 | );
427 | runOnlyForDeploymentPostprocessing = 0;
428 | };
429 | /* End PBXSourcesBuildPhase section */
430 |
431 | /* Begin PBXTargetDependency section */
432 | CB469B521A50D8A40000A950 /* PBXTargetDependency */ = {
433 | isa = PBXTargetDependency;
434 | target = CB469B3F1A50D8A40000A950 /* Handmade Hero OSX */;
435 | targetProxy = CB469B511A50D8A40000A950 /* PBXContainerItemProxy */;
436 | };
437 | /* End PBXTargetDependency section */
438 |
439 | /* Begin PBXVariantGroup section */
440 | CB469B491A50D8A40000A950 /* MainMenu.xib */ = {
441 | isa = PBXVariantGroup;
442 | children = (
443 | CB469B4A1A50D8A40000A950 /* Base */,
444 | );
445 | name = MainMenu.xib;
446 | sourceTree = "";
447 | };
448 | /* End PBXVariantGroup section */
449 |
450 | /* Begin XCBuildConfiguration section */
451 | CB469B581A50D8A40000A950 /* Debug */ = {
452 | isa = XCBuildConfiguration;
453 | buildSettings = {
454 | ALWAYS_SEARCH_USER_PATHS = NO;
455 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
456 | CLANG_CXX_LIBRARY = "libc++";
457 | CLANG_ENABLE_MODULES = YES;
458 | CLANG_ENABLE_OBJC_ARC = YES;
459 | CLANG_WARN_BOOL_CONVERSION = YES;
460 | CLANG_WARN_CONSTANT_CONVERSION = YES;
461 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
462 | CLANG_WARN_EMPTY_BODY = YES;
463 | CLANG_WARN_ENUM_CONVERSION = YES;
464 | CLANG_WARN_INT_CONVERSION = YES;
465 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
466 | CLANG_WARN_UNREACHABLE_CODE = YES;
467 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
468 | CODE_SIGN_IDENTITY = "-";
469 | COPY_PHASE_STRIP = NO;
470 | ENABLE_STRICT_OBJC_MSGSEND = YES;
471 | GCC_C_LANGUAGE_STANDARD = gnu99;
472 | GCC_DYNAMIC_NO_PIC = NO;
473 | GCC_OPTIMIZATION_LEVEL = 0;
474 | GCC_PREPROCESSOR_DEFINITIONS = (
475 | "DEBUG=1",
476 | "$(inherited)",
477 | );
478 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
479 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
480 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
481 | GCC_WARN_UNDECLARED_SELECTOR = YES;
482 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
483 | GCC_WARN_UNUSED_FUNCTION = YES;
484 | GCC_WARN_UNUSED_VARIABLE = YES;
485 | MACOSX_DEPLOYMENT_TARGET = 10.9;
486 | MTL_ENABLE_DEBUG_INFO = YES;
487 | ONLY_ACTIVE_ARCH = YES;
488 | SDKROOT = macosx;
489 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
490 | };
491 | name = Debug;
492 | };
493 | CB469B591A50D8A40000A950 /* Release */ = {
494 | isa = XCBuildConfiguration;
495 | buildSettings = {
496 | ALWAYS_SEARCH_USER_PATHS = NO;
497 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
498 | CLANG_CXX_LIBRARY = "libc++";
499 | CLANG_ENABLE_MODULES = YES;
500 | CLANG_ENABLE_OBJC_ARC = YES;
501 | CLANG_WARN_BOOL_CONVERSION = YES;
502 | CLANG_WARN_CONSTANT_CONVERSION = YES;
503 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
504 | CLANG_WARN_EMPTY_BODY = YES;
505 | CLANG_WARN_ENUM_CONVERSION = YES;
506 | CLANG_WARN_INT_CONVERSION = YES;
507 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
508 | CLANG_WARN_UNREACHABLE_CODE = YES;
509 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
510 | CODE_SIGN_IDENTITY = "-";
511 | COPY_PHASE_STRIP = YES;
512 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
513 | ENABLE_NS_ASSERTIONS = NO;
514 | ENABLE_STRICT_OBJC_MSGSEND = YES;
515 | GCC_C_LANGUAGE_STANDARD = gnu99;
516 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
517 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
518 | GCC_WARN_UNDECLARED_SELECTOR = YES;
519 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
520 | GCC_WARN_UNUSED_FUNCTION = YES;
521 | GCC_WARN_UNUSED_VARIABLE = YES;
522 | MACOSX_DEPLOYMENT_TARGET = 10.9;
523 | MTL_ENABLE_DEBUG_INFO = NO;
524 | SDKROOT = macosx;
525 | };
526 | name = Release;
527 | };
528 | CB469B5B1A50D8A40000A950 /* Debug */ = {
529 | isa = XCBuildConfiguration;
530 | buildSettings = {
531 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
532 | COMBINE_HIDPI_IMAGES = YES;
533 | GCC_PREPROCESSOR_DEFINITIONS = (
534 | "DEBUG=1",
535 | "HANDMADE_INTERNAL=1",
536 | "HANDMADE_SLOW=1",
537 | );
538 | INFOPLIST_FILE = "Handmade Hero OSX/Info.plist";
539 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
540 | PRODUCT_NAME = "$(TARGET_NAME)";
541 | SWIFT_OBJC_BRIDGING_HEADER = "Handmade Hero OSX/Handmade Hero OSX-Bridging-Header.h";
542 | };
543 | name = Debug;
544 | };
545 | CB469B5C1A50D8A40000A950 /* Release */ = {
546 | isa = XCBuildConfiguration;
547 | buildSettings = {
548 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
549 | COMBINE_HIDPI_IMAGES = YES;
550 | GCC_PREPROCESSOR_DEFINITIONS = "HANDMADE_INTERNAL=1";
551 | INFOPLIST_FILE = "Handmade Hero OSX/Info.plist";
552 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
553 | PRODUCT_NAME = "$(TARGET_NAME)";
554 | SWIFT_OBJC_BRIDGING_HEADER = "Handmade Hero OSX/Handmade Hero OSX-Bridging-Header.h";
555 | };
556 | name = Release;
557 | };
558 | CB469B5E1A50D8A40000A950 /* Debug */ = {
559 | isa = XCBuildConfiguration;
560 | buildSettings = {
561 | BUNDLE_LOADER = "$(TEST_HOST)";
562 | COMBINE_HIDPI_IMAGES = YES;
563 | FRAMEWORK_SEARCH_PATHS = (
564 | "$(DEVELOPER_FRAMEWORKS_DIR)",
565 | "$(inherited)",
566 | );
567 | GCC_PREPROCESSOR_DEFINITIONS = (
568 | "DEBUG=1",
569 | "$(inherited)",
570 | );
571 | INFOPLIST_FILE = "Handmade Hero OSXTests/Info.plist";
572 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
573 | PRODUCT_NAME = "$(TARGET_NAME)";
574 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Handmade Hero OSX.app/Contents/MacOS/Handmade Hero OSX";
575 | };
576 | name = Debug;
577 | };
578 | CB469B5F1A50D8A40000A950 /* Release */ = {
579 | isa = XCBuildConfiguration;
580 | buildSettings = {
581 | BUNDLE_LOADER = "$(TEST_HOST)";
582 | COMBINE_HIDPI_IMAGES = YES;
583 | FRAMEWORK_SEARCH_PATHS = (
584 | "$(DEVELOPER_FRAMEWORKS_DIR)",
585 | "$(inherited)",
586 | );
587 | INFOPLIST_FILE = "Handmade Hero OSXTests/Info.plist";
588 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
589 | PRODUCT_NAME = "$(TARGET_NAME)";
590 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Handmade Hero OSX.app/Contents/MacOS/Handmade Hero OSX";
591 | };
592 | name = Release;
593 | };
594 | /* End XCBuildConfiguration section */
595 |
596 | /* Begin XCConfigurationList section */
597 | CB469B3B1A50D8A40000A950 /* Build configuration list for PBXProject "Handmade Hero OSX" */ = {
598 | isa = XCConfigurationList;
599 | buildConfigurations = (
600 | CB469B581A50D8A40000A950 /* Debug */,
601 | CB469B591A50D8A40000A950 /* Release */,
602 | );
603 | defaultConfigurationIsVisible = 0;
604 | defaultConfigurationName = Release;
605 | };
606 | CB469B5A1A50D8A40000A950 /* Build configuration list for PBXNativeTarget "Handmade Hero OSX" */ = {
607 | isa = XCConfigurationList;
608 | buildConfigurations = (
609 | CB469B5B1A50D8A40000A950 /* Debug */,
610 | CB469B5C1A50D8A40000A950 /* Release */,
611 | );
612 | defaultConfigurationIsVisible = 0;
613 | defaultConfigurationName = Release;
614 | };
615 | CB469B5D1A50D8A40000A950 /* Build configuration list for PBXNativeTarget "Handmade Hero OSXTests" */ = {
616 | isa = XCConfigurationList;
617 | buildConfigurations = (
618 | CB469B5E1A50D8A40000A950 /* Debug */,
619 | CB469B5F1A50D8A40000A950 /* Release */,
620 | );
621 | defaultConfigurationIsVisible = 0;
622 | defaultConfigurationName = Release;
623 | };
624 | /* End XCConfigurationList section */
625 | };
626 | rootObject = CB469B381A50D8A40000A950 /* Project object */;
627 | }
628 |
--------------------------------------------------------------------------------