| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Learning SDL3 with C23 by doing the oldest trick in graphics: keep a plain array of pixels in memory, draw into it with your own code, and hand the whole thing to the GPU once per frame.
src/main.c owns the window, the event loop and the frame pacing. framelib is the drawing layer — it knows nothing about SDL, it just writes 32-bit colors into a flat array.
The framebuffer is a uint32_t[320 * 200]. Every frame it is uploaded to a streaming texture, which the GPU then scales up to fill the window:
framebuffer SDL_UpdateTexture SDL_RenderTexture
uint32_t[320*200] ──────────────────────► texture ──────────────► window
(320x200) (1280x800)
The window is 4x the framebuffer and the texture uses SDL_SCALEMODE_NEAREST, so pixels stay crisp blocks instead of being blurred by interpolation.
The loop is capped at 60 fps using SDL_GetPerformanceCounter to measure the frame and SDL_DelayPrecise to sleep off the remainder. SDL_Delay would do too, but it only takes whole milliseconds: a 16.67 ms budget rounds to 16 or 17 and the frame time jitters. SDL_DelayPrecise takes nanoseconds and spins for the last stretch rather than handing it back to the scheduler.
macOS with Homebrew:
brew install sdl3 gccSDL3 is found through pkg-config, so no paths are hardcoded for it.
make # build into build/
make run # build, then run
make sanitize # build and run under AddressSanitizer + UBSan
make format # rewrite the sources using .clang-format
make clean # remove build/make sanitize builds into build/sanitize/ so the instrumented objects never mix with the plain ones. It is the quickest way to catch an fb_put_pixel call that runs off the end of the framebuffer — the function does no bounds checking by design, and without ASan such a write just corrupts whatever follows.
The compiler defaults to the newest gcc-NN in your Homebrew prefix, falling back to cc if there is none. Override it whenever you like:
make CC=cc # Apple clang instead
make -j$(sysctl -n hw.ncpu) # parallel buildinclude/framelib.h is documented with Doxygen comments, in the same style SDL3 uses in its own headers.
brew install doxygen # once
make docs # generate build/docs/html
make docs-open # generate, then open it in a browserThe generated site uses this README as its landing page. Output goes under build/, so it is never committed, and make clean removes it along with the object files.
├── Makefile one non-recursive makefile for the whole project
├── Doxyfile documentation settings
├── compile_flags.txt tells clangd how to parse the sources
├── .clang-format formatting rules
├── include/
│ └── framelib.h framelib's public API
├── src/
│ ├── main.c window, event loop, frame pacing
│ └── framelib.c drawing primitives
└── build/ all build output (gitignored)
There is deliberately one Makefile rather than one per directory. Recursive make cannot see dependencies across directory boundaries, so editing include/framelib.h would leave a stale main.o behind. Here a single makefile uses -MMD -MP to generate real header dependencies, and touching a header rebuilds exactly what depends on it.
The committed .vscode/ config uses clangd for IntelliSense and disables the C/C++ extension's own engine, including its Tag Parser fallback. Running both at once produces duplicated and contradictory diagnostics; the Tag Parser in particular cannot handle C23 and will report errors inside system headers that compile perfectly well.
clangd reads compile_flags.txt to learn the include paths and language standard. The C/C++ extension is still used for debugging (F5), which builds first and launches under lldb.
This is a macOS/Homebrew setup. compile_flags.txt and .vscode/c_cpp_properties.json still refer to /opt/homebrew, so building on Linux means dropping those entries — pkg-config already supplies SDL3's real location, and the Makefile no longer hardcodes a compiler path: it looks for the newest Homebrew gcc-NN and falls back to cc.
C23 itself needs GCC ≥ 14 or Clang ≥ 18. Apple Clang from Xcode 16 accepts -std=c23, so make CC=cc works, but it still lacks [[reproducible]] and [[unsequenced]] — nothing here uses them.
Apache License 2.0 — see LICENSE.
| Back | FazBrowse Home | New Git URL |