begin macos port

This commit is contained in:
2026-03-03 10:00:38 -05:00
parent 7e298faadd
commit ad30ca8cb7
13 changed files with 2205 additions and 124 deletions

View File

@@ -4,21 +4,33 @@ Graphical interface for automatically recording samples from existing analog aud
## Build
### Windows
Requires MSVC (Visual Studio 2019 Build Tools or later) with the Windows SDK and C++20 support.
Open a Developer Command Prompt, then:
```
cl /nologo nob.c
nob.exe debug
build\autosample.exe
cl /nologo build.c
build.exe debug
build_debug\autosample.exe
```
The first command is a one-time bootstrap. After that, `nob.exe` detects changes to `nob.c` and rebuilds itself automatically. Pass `debug` for a debug build (default is release). Pass `clean` to wipe the build directory.
### macOS
Requires Xcode Command Line Tools (`xcode-select --install`).
```
cc build.c -o build
./build debug
open build_debug/autosample.app
```
The first command is a one-time bootstrap. After that, `./build` detects changes to `build.c` and rebuilds itself automatically. Pass `debug` for a debug build (output in `build_debug/`) or omit for release (`build_release/`). Pass `clean` to wipe the build directory.
## Architecture
The project uses a **unity build**: `src/main.cpp` includes all other `.cpp` files, producing a single translation unit compiled with one `$CC` invocation.
The project uses a **unity build**: `src/main.cpp` includes all other `.cpp`/`.mm` files, producing a single translation unit compiled with one compiler invocation. Platform selection is handled with `#ifdef __APPLE__` guards.
### Base layer (`src/base/`)
@@ -26,7 +38,10 @@ Foundational types and utilities shared across the project. Provides sized integ
### Platform layer (`src/platform/`)
Abstracts window creation, event polling, and native handles behind a C-style API with opaque `PlatformWindow` handles. The Win32 backend (`platform_win32.cpp`) implements the interface. Other backends can be added without touching the rest of the code.
Abstracts window creation, event polling, menus, clipboard, and native handles behind a C-style API with opaque `PlatformWindow` handles.
- **Windows**: `platform_win32.cpp` — Win32/HWND, `WM_*` message loop
- **macOS**: `platform_macos.mm` — Cocoa/AppKit, NSWindow, NSTextInputClient
### UI layer (`src/ui/`)
@@ -39,26 +54,39 @@ The application layout is built in `main.cpp` using Clay macros directly. Panel
### Renderer (`src/renderer/`)
DirectX 12 renderer with a custom SDF-based pipeline for UI rendering. Processes Clay's `Clay_RenderCommandArray` output directly — no intermediate scene graph.
Custom SDF-based pipeline for UI rendering. Processes Clay's `Clay_RenderCommandArray` output directly — no intermediate scene graph.
- **Font atlas**: Built at startup using GDI (`TextOutA` into a DIB section), converted to a single-channel R8 texture. Covers ASCII 32126 (Segoe UI).
- **Text measurement**: GDI-based (`GetTextExtentPoint32A`), exposed to Clay via the `Clay_SetMeasureTextFunction` callback.
- **Render commands**: Handles `RECTANGLE` (SDF rounded rect with corner radius), `BORDER` (individual sides as thin rects), `TEXT` (glyph quads from the font atlas), and `SCISSOR_START`/`SCISSOR_END` (clip regions).
- **Vertex format**: Position, UV, color, rect bounds, corner radius, border thickness, softness, and mode (0 = SDF rect, 1 = textured glyph). Alpha blending with premultiplied SDF anti-aliasing.
- **Windows**: `renderer_dx12.cpp` — DirectX 12, HLSL shaders, GDI font atlas (Segoe UI)
- **macOS**: `renderer_metal.mm` — Metal, MSL shaders, Core Text font atlas (SF Pro)
Both renderers share the same vertex format (18 floats), SDF rounded-rect shader, and Clay command processing logic. Text measurement uses GDI on Windows and Core Text on macOS.
### Audio (`src/audio/`)
Audio device enumeration and output with test tone generation.
- **Windows**: `audio_asio.cpp` — ASIO driver via COM, registry enumeration, multi-format sample writing
- **macOS**: `audio_coreaudio.cpp` — CoreAudio with AUGraph/HAL Output, Float32 non-interleaved
### MIDI (`src/midi/`)
Enumerates MIDI input and output devices via the Win32 multimedia API (`midiInGetDevCapsA` / `midiOutGetDevCapsA`). Provides a simple `MidiEngine` with device listing and refresh.
MIDI device enumeration with real-time input monitoring.
- **Windows**: `midi_win32.cpp` — Win32 multimedia API (`midiIn*` / `midiOut*`)
- **macOS**: `midi_coremidi.cpp` — CoreMIDI client with single input port, source connection
## Project structure
```
nob.c Build script (compiled to nob.exe)
nob.h nob build system (vendored, single-header)
build.c Build script (cc build.c -o nob)
vendor/
nob/
nob.h nob build system (vendored, single-header)
clay/
clay.h Clay v0.14 (modified for MSVC C++ compatibility)
src/
main.cpp Entry point, unity build includes, Clay layout
menus.cpp Menu bar setup
theme.cpp Theme stub
base/
base_core.h Sized types, macros
base_arena.h / .cpp Arena allocator
@@ -68,19 +96,23 @@ src/
platform/
platform.h Window management API (platform-agnostic)
platform_win32.cpp Win32 implementation
platform_macos.mm macOS Cocoa implementation
renderer/
renderer.h Renderer API (graphics-agnostic)
renderer_dx12.cpp DirectX 12 implementation, SDF pipeline, font atlas
renderer_dx12.cpp DirectX 12 implementation
renderer_metal.mm Metal implementation
ui/
ui_core.h Clay wrapper types and lifecycle API
ui_core.cpp Clay init, text measurement bridge, theme
ui_widgets.h / .cpp Widget stubs (reserved)
audio/
audio.h Audio device and playback API
audio_asio.cpp Windows ASIO implementation
audio_coreaudio.cpp macOS CoreAudio implementation
midi/
midi.h MIDI device enumeration API
midi_win32.cpp Win32 multimedia implementation
vendor/
clay/
clay.h Clay v0.14 (modified for MSVC C++ compatibility)
midi_coremidi.cpp macOS CoreMIDI implementation
```
### Modifications to `vendor/clay/clay.h`
@@ -95,7 +127,7 @@ These patches allow the entire project (including Clay) to compile as a single C
## Code style
This project is written in C-style C++. We use `.cpp` files and a small subset of C++ features (default struct values, function overloading, namespaces where useful) but avoid the rest. No classes, no inheritance, limit templates, no exceptions, no RAII, avoid STL containers or algorithms. Data is plain structs. Functions operate on those structs, or pointers to them.
This project is written in C-style C++. We use `.cpp` files and a small subset of C++ features (default struct values, function overloading, namespaces where useful) but avoid the rest. No classes, no inheritance, limit templates, no exceptions, no RTTI, avoid STL containers or algorithms. Data is plain structs. Functions operate on those structs, or pointers to them. macOS files use `.mm` extension for Objective-C++ interop.
Memory should be managed with arena allocators where possible rather than individual `malloc`/`free` or `new`/`delete` calls. Arenas make allocation fast, avoid fragmentation, and simplify cleanup.
@@ -106,7 +138,7 @@ Memory should be managed with arena allocators where possible rather than indivi
## Dependencies
All dependencies are vendored as source. Nothing to download or install beyond the Windows SDK.
All dependencies are vendored as source. On Windows, nothing to install beyond the Windows SDK. On macOS, only Xcode Command Line Tools are needed — all frameworks (Metal, Cocoa, CoreAudio, CoreMIDI, CoreText, etc.) ship with the OS.
- [nob.h](https://github.com/tsoding/nob.h) — build system
- [Clay](https://github.com/nicbarker/clay) — single-header C layout library (v0.14, with MSVC C++ patches)