initial commit

This commit is contained in:
robojerk 2025-12-15 16:03:37 -08:00
commit 6d27a8ed3a
17 changed files with 4440 additions and 0 deletions

View file

@ -0,0 +1,103 @@
/// Audio System Protocol - Platform-agnostic audio handling
/// This module contains ONLY protocol definitions with no platform-specific imports
import Foundation
// MARK: - Audio Types
/// Audio source handle
public struct AudioHandle: Hashable, Sendable {
public let id: UUID
public init(id: UUID = UUID()) { self.id = id }
}
/// Audio configuration
public struct AudioConfig: Sendable {
public var sampleRate: Int
public var channels: Int
public var bufferSize: Int
public init(sampleRate: Int = 44100, channels: Int = 2, bufferSize: Int = 4096) {
self.sampleRate = sampleRate
self.channels = channels
self.bufferSize = bufferSize
}
}
/// 3D audio source properties
public struct AudioSource3D: Sendable {
public var position: SIMD3<Float>
public var velocity: SIMD3<Float>
public var volume: Float
public var pitch: Float
public var looping: Bool
public var spatialize: Bool
public init(position: SIMD3<Float> = .zero, velocity: SIMD3<Float> = .zero,
volume: Float = 1.0, pitch: Float = 1.0, looping: Bool = false, spatialize: Bool = true) {
self.position = position
self.velocity = velocity
self.volume = volume
self.pitch = pitch
self.looping = looping
self.spatialize = spatialize
}
}
/// Audio listener properties (typically the camera)
public struct AudioListener: Sendable {
public var position: SIMD3<Float>
public var velocity: SIMD3<Float>
public var forward: SIMD3<Float>
public var up: SIMD3<Float>
public init(position: SIMD3<Float> = .zero, velocity: SIMD3<Float> = .zero,
forward: SIMD3<Float> = SIMD3<Float>(0, 0, -1), up: SIMD3<Float> = SIMD3<Float>(0, 1, 0)) {
self.position = position
self.velocity = velocity
self.forward = forward
self.up = up
}
}
// MARK: - Audio Engine Protocol
/// Audio system abstraction - all platform-specific audio implementations must conform
public protocol AudioEngine: Sendable {
/// Initialize the audio system
func initialize(config: AudioConfig) async throws
/// Load an audio clip from file
func loadAudio(path: String) async throws -> AudioHandle
/// Load audio from raw PCM data
func loadAudioFromData(data: Data, sampleRate: Int, channels: Int) async throws -> AudioHandle
/// Play an audio source
func play(handle: AudioHandle, source: AudioSource3D) throws
/// Stop an audio source
func stop(handle: AudioHandle) throws
/// Pause an audio source
func pause(handle: AudioHandle) throws
/// Resume a paused audio source
func resume(handle: AudioHandle) throws
/// Update audio source properties
func updateSource(handle: AudioHandle, source: AudioSource3D) throws
/// Set listener properties (camera/player position)
func setListener(listener: AudioListener) throws
/// Set master volume
func setMasterVolume(_ volume: Float) throws
/// Update audio system (called each frame)
func update(deltaTime: Float) throws
/// Shutdown the audio system
func shutdown() async
}

View file

@ -0,0 +1,125 @@
/// Input System Protocol - Platform-agnostic input handling
/// This module contains ONLY protocol definitions with no platform-specific imports
import Foundation
// MARK: - Input Types
/// Keyboard key codes
public enum KeyCode: Int, Sendable {
case unknown = 0
case space = 32
case apostrophe = 39
case comma = 44
case minus = 45
case period = 46
case slash = 47
case key0 = 48, key1, key2, key3, key4, key5, key6, key7, key8, key9
case semicolon = 59
case equal = 61
case a = 65, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
case leftBracket = 91
case backslash = 92
case rightBracket = 93
case graveAccent = 96
case escape = 256
case enter = 257
case tab = 258
case backspace = 259
case insert = 260
case delete = 261
case right = 262
case left = 263
case down = 264
case up = 265
case pageUp = 266
case pageDown = 267
case home = 268
case end = 269
case capsLock = 280
case scrollLock = 281
case numLock = 282
case printScreen = 283
case pause = 284
case f1 = 290, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12
case leftShift = 340
case leftControl = 341
case leftAlt = 342
case leftSuper = 343
case rightShift = 344
case rightControl = 345
case rightAlt = 346
case rightSuper = 347
}
/// Mouse button codes
public enum MouseButton: Int, Sendable {
case left = 0
case right = 1
case middle = 2
case button4 = 3
case button5 = 4
}
/// Input action state
public enum InputAction: Sendable {
case press
case release
case repeat_
}
/// Input event types
public enum InputEvent: Sendable {
case keyEvent(key: KeyCode, action: InputAction)
case mouseButton(button: MouseButton, action: InputAction)
case mouseMove(x: Double, y: Double)
case mouseScroll(xOffset: Double, yOffset: Double)
case gamepadButton(gamepadId: Int, button: Int, action: InputAction)
case gamepadAxis(gamepadId: Int, axis: Int, value: Float)
}
// MARK: - Input Handler Protocol
/// Input system abstraction - all platform-specific input implementations must conform
public protocol InputHandler: Sendable {
/// Initialize the input system
func initialize() async throws
/// Poll for input events (called each frame)
func pollEvents() -> [InputEvent]
/// Check if a key is currently pressed
func isKeyPressed(_ key: KeyCode) -> Bool
/// Check if a mouse button is currently pressed
func isMouseButtonPressed(_ button: MouseButton) -> Bool
/// Get current mouse position
func getMousePosition() -> (x: Double, y: Double)
/// Set mouse cursor visibility
func setCursorVisible(_ visible: Bool)
/// Set mouse cursor mode (normal, hidden, locked)
func setCursorMode(_ mode: CursorMode)
/// Get connected gamepad count
func getGamepadCount() -> Int
/// Check if a gamepad is connected
func isGamepadConnected(_ gamepadId: Int) -> Bool
/// Get gamepad name
func getGamepadName(_ gamepadId: Int) -> String?
/// Shutdown the input system
func shutdown() async
}
/// Cursor display mode
public enum CursorMode: Sendable {
case normal
case hidden
case locked
}

View file

@ -0,0 +1,197 @@
/// RendererAPI - Protocol Definitions for Platform Abstraction
/// This module contains ONLY protocol definitions with no platform-specific imports
import Foundation
// MARK: - Core Rendering Types
/// Represents a 3D scene to be rendered
public struct Scene {
public var entities: [Entity]
public var camera: Camera
public var lights: [Light]
public init(entities: [Entity] = [], camera: Camera, lights: [Light] = []) {
self.entities = entities
self.camera = camera
self.lights = lights
}
}
/// Represents a renderable entity in the scene
public struct Entity {
public var id: UUID
public var transform: Transform
public var mesh: MeshHandle
public var material: MaterialHandle
public init(id: UUID = UUID(), transform: Transform, mesh: MeshHandle, material: MaterialHandle) {
self.id = id
self.transform = transform
self.mesh = mesh
self.material = material
}
}
/// Camera configuration
public struct Camera {
public var position: SIMD3<Float>
public var rotation: SIMD4<Float> // Quaternion
public var fieldOfView: Float
public var nearPlane: Float
public var farPlane: Float
public init(position: SIMD3<Float> = .zero, rotation: SIMD4<Float> = SIMD4<Float>(0, 0, 0, 1),
fieldOfView: Float = 60.0, nearPlane: Float = 0.1, farPlane: Float = 1000.0) {
self.position = position
self.rotation = rotation
self.fieldOfView = fieldOfView
self.nearPlane = nearPlane
self.farPlane = farPlane
}
}
/// Transform component
public struct Transform {
public var position: SIMD3<Float>
public var rotation: SIMD4<Float> // Quaternion
public var scale: SIMD3<Float>
public init(position: SIMD3<Float> = .zero, rotation: SIMD4<Float> = SIMD4<Float>(0, 0, 0, 1),
scale: SIMD3<Float> = SIMD3<Float>(1, 1, 1)) {
self.position = position
self.rotation = rotation
self.scale = scale
}
}
/// Light source
public struct Light {
public enum LightType {
case directional
case point
case spot
}
public var type: LightType
public var position: SIMD3<Float>
public var direction: SIMD3<Float>
public var color: SIMD3<Float>
public var intensity: Float
public init(type: LightType, position: SIMD3<Float> = .zero, direction: SIMD3<Float> = SIMD3<Float>(0, -1, 0),
color: SIMD3<Float> = SIMD3<Float>(1, 1, 1), intensity: Float = 1.0) {
self.type = type
self.position = position
self.direction = direction
self.color = color
self.intensity = intensity
}
}
/// Opaque handle for mesh resources
public struct MeshHandle: Hashable {
public let id: UUID
public init(id: UUID = UUID()) { self.id = id }
}
/// Opaque handle for material resources
public struct MaterialHandle: Hashable {
public let id: UUID
public init(id: UUID = UUID()) { self.id = id }
}
/// Opaque handle for texture resources
public struct TextureHandle: Hashable {
public let id: UUID
public init(id: UUID = UUID()) { self.id = id }
}
// MARK: - Renderer Protocol
/// Primary rendering abstraction - all rendering backends must conform to this
public protocol Renderer: Sendable {
/// Initialize the renderer with the given configuration
func initialize(config: RendererConfig) async throws
/// Begin a new frame
func beginFrame() throws
/// Draw the current scene
func draw(scene: Scene) throws
/// End the current frame and present
func endFrame() throws
/// Shutdown and cleanup resources
func shutdown() async
/// Load a mesh into GPU memory
func loadMesh(vertices: [Vertex], indices: [UInt32]) async throws -> MeshHandle
/// Load a texture into GPU memory
func loadTexture(data: Data, width: Int, height: Int, format: TextureFormat) async throws -> TextureHandle
/// Create a material
func createMaterial(albedoTexture: TextureHandle?, normalTexture: TextureHandle?) async throws -> MaterialHandle
/// Get renderer capabilities and information
var info: RendererInfo { get }
}
/// Renderer configuration
public struct RendererConfig: Sendable {
public var windowHandle: UnsafeMutableRawPointer?
public var width: Int
public var height: Int
public var vsyncEnabled: Bool
public var msaaSamples: Int
public init(windowHandle: UnsafeMutableRawPointer? = nil, width: Int = 1920, height: Int = 1080,
vsyncEnabled: Bool = true, msaaSamples: Int = 4) {
self.windowHandle = windowHandle
self.width = width
self.height = height
self.vsyncEnabled = vsyncEnabled
self.msaaSamples = msaaSamples
}
}
/// Renderer information
public struct RendererInfo: Sendable {
public var apiName: String
public var apiVersion: String
public var deviceName: String
public var maxTextureSize: Int
public init(apiName: String, apiVersion: String, deviceName: String, maxTextureSize: Int) {
self.apiName = apiName
self.apiVersion = apiVersion
self.deviceName = deviceName
self.maxTextureSize = maxTextureSize
}
}
/// Vertex data structure
public struct Vertex: Sendable {
public var position: SIMD3<Float>
public var normal: SIMD3<Float>
public var uv: SIMD2<Float>
public var tangent: SIMD3<Float>
public init(position: SIMD3<Float>, normal: SIMD3<Float>, uv: SIMD2<Float>, tangent: SIMD3<Float> = .zero) {
self.position = position
self.normal = normal
self.uv = uv
self.tangent = tangent
}
}
/// Texture format enumeration
public enum TextureFormat: Sendable {
case rgba8
case rgba16f
case rgba32f
case depth24stencil8
}

View file

@ -0,0 +1,72 @@
/// Window Management Protocol - Platform-agnostic window handling
/// This module contains ONLY protocol definitions with no platform-specific imports
import Foundation
// MARK: - Window Types
/// Window configuration
public struct WindowConfig: Sendable {
public var title: String
public var width: Int
public var height: Int
public var fullscreen: Bool
public var resizable: Bool
public var vsyncEnabled: Bool
public init(title: String = "SportsBallEngine", width: Int = 1920, height: Int = 1080,
fullscreen: Bool = false, resizable: Bool = true, vsyncEnabled: Bool = true) {
self.title = title
self.width = width
self.height = height
self.fullscreen = fullscreen
self.resizable = resizable
self.vsyncEnabled = vsyncEnabled
}
}
/// Window event types
public enum WindowEvent: Sendable {
case close
case resize(width: Int, height: Int)
case focus(focused: Bool)
case minimize
case maximize
case restore
}
// MARK: - Window Manager Protocol
/// Window system abstraction - all platform-specific window implementations must conform
public protocol WindowManager: Sendable {
/// Create and initialize a window with the given configuration
func createWindow(config: WindowConfig) async throws
/// Check if the window should close
func shouldClose() -> Bool
/// Process window events (called each frame)
func processEvents() -> [WindowEvent]
/// Get current window size
func getSize() -> (width: Int, height: Int)
/// Set window size
func setSize(width: Int, height: Int) throws
/// Set window title
func setTitle(_ title: String) throws
/// Toggle fullscreen mode
func setFullscreen(_ fullscreen: Bool) throws
/// Get native window handle (for renderer initialization)
func getNativeHandle() -> UnsafeMutableRawPointer?
/// Swap buffers / present frame
func swapBuffers() throws
/// Destroy the window and cleanup
func destroyWindow() async
}