Skip to content

Migrate from SDL2 to SDL3 Renderer API#9

Merged
forketyfork merged 2 commits into
mainfrom
sdl3-migration
Dec 31, 2025
Merged

Migrate from SDL2 to SDL3 Renderer API#9
forketyfork merged 2 commits into
mainfrom
sdl3-migration

Conversation

@forketyfork
Copy link
Copy Markdown
Owner

Migrates the project from SDL2 to SDL3 using the high-level Renderer API (not the low-level GPU API). SDL3 Renderer provides automatic batching and improved performance while maintaining API familiarity with SDL2.

Key changes:

Dependencies (flake.nix, build.zig):

  • Update to SDL3 3.2.24 and SDL3_ttf 3.2.2 from nixpkgs-unstable
  • Add library search paths for SDL3 and SDL3_ttf
  • Update environment variables (SDL2_* → SDL3_*)

C bindings (src/c.zig):

  • Update headers: SDL2/SDL.h → SDL3/SDL.h
  • Rename event constants: SDL_QUIT → SDL_EVENT_QUIT, etc.
  • Update function names: SDL_RenderDrawLine → SDL_RenderLine, etc.
  • Add SDL_StartTextInput/SDL_StopTextInput bindings (critical for text input)
  • Remove deprecated: SDL_WINDOW_SHOWN, SDL_HINT_RENDER_SCALE_QUALITY
  • Add new types: SDL_FRect, SDL_FColor, SDL_Keycode, SDL_Keymod

Application code (src/main.zig):

  • SDL_Init() now returns bool instead of int
  • SDL_CreateWindow() takes 4 params (removed SDL_WINDOWPOS_CENTERED)
  • SDL_CreateRenderer() takes 2 params instead of 3
  • Enable text input with SDL_StartTextInput(window) after window creation
  • Update event handling: All SDL_* → SDL_EVENT_*
  • Keyboard: event.key.keysym → event.key.key with separate mod tracking
  • Mouse coordinates: Convert floats with @intFromFloat
  • All rendering: SDL_Rect → SDL_FRect with float conversions
  • Rename encodeKey → encodeKeyWithMod with new signature

Font rendering (src/font.zig):

  • TTF_OpenFont: size parameter now float
  • TTF_SizeText → TTF_GetStringSize with length parameter and bool return
  • Check TTF_GetStringSize return value to avoid 0x0 cell dimensions
  • TTF_RenderText_Blended: now takes length parameter
  • SDL_FreeSurface → SDL_DestroySurface
  • SDL_QueryTexture → SDL_GetTextureSize (returns floats)
  • SDL_RenderCopy → SDL_RenderTexture with SDL_FRect
  • SDL_ScaleModeLinear → SDL_SCALEMODE_LINEAR
  • TTF_GetError() → SDL_GetError()

Critical fix:

  • SDL3 requires explicit SDL_StartTextInput(window) call to receive SDL_EVENT_TEXT_INPUT events. Without this, printable characters are dropped and typing doesn't work (only key events like Enter work).

Tested on macOS with successful build and runtime verification.

Migrates the project from SDL2 to SDL3 using the high-level Renderer API
(not the low-level GPU API). SDL3 Renderer provides automatic batching and
improved performance while maintaining API familiarity with SDL2.

Key changes:

Dependencies (flake.nix, build.zig):
- Update to SDL3 3.2.24 and SDL3_ttf 3.2.2 from nixpkgs-unstable
- Add library search paths for SDL3 and SDL3_ttf
- Update environment variables (SDL2_* → SDL3_*)

C bindings (src/c.zig):
- Update headers: SDL2/SDL.h → SDL3/SDL.h
- Rename event constants: SDL_QUIT → SDL_EVENT_QUIT, etc.
- Update function names: SDL_RenderDrawLine → SDL_RenderLine, etc.
- Add SDL_StartTextInput/SDL_StopTextInput bindings (critical for text input)
- Remove deprecated: SDL_WINDOW_SHOWN, SDL_HINT_RENDER_SCALE_QUALITY
- Add new types: SDL_FRect, SDL_FColor, SDL_Keycode, SDL_Keymod

Application code (src/main.zig):
- SDL_Init() now returns bool instead of int
- SDL_CreateWindow() takes 4 params (removed SDL_WINDOWPOS_CENTERED)
- SDL_CreateRenderer() takes 2 params instead of 3
- Enable text input with SDL_StartTextInput(window) after window creation
- Update event handling: All SDL_* → SDL_EVENT_*
- Keyboard: event.key.keysym → event.key.key with separate mod tracking
- Mouse coordinates: Convert floats with @intFromFloat
- All rendering: SDL_Rect → SDL_FRect with float conversions
- Rename encodeKey → encodeKeyWithMod with new signature

Font rendering (src/font.zig):
- TTF_OpenFont: size parameter now float
- TTF_SizeText → TTF_GetStringSize with length parameter and bool return
- Check TTF_GetStringSize return value to avoid 0x0 cell dimensions
- TTF_RenderText_Blended: now takes length parameter
- SDL_FreeSurface → SDL_DestroySurface
- SDL_QueryTexture → SDL_GetTextureSize (returns floats)
- SDL_RenderCopy → SDL_RenderTexture with SDL_FRect
- SDL_ScaleModeLinear → SDL_SCALEMODE_LINEAR
- TTF_GetError() → SDL_GetError()

Critical fix:
- SDL3 requires explicit SDL_StartTextInput(window) call to receive
  SDL_EVENT_TEXT_INPUT events. Without this, printable characters are
  dropped and typing doesn't work (only key events like Enter work).

Tested on macOS with successful build and runtime verification.
@forketyfork forketyfork requested a review from Copilot December 31, 2025 10:52
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the project from SDL2 to SDL3 using the high-level Renderer API. The migration updates dependencies, C bindings, and application code to align with SDL3's API changes while maintaining functionality.

Key changes:

  • Update dependencies to SDL3 3.2.24 and SDL3_ttf 3.2.2 from nixpkgs-unstable
  • Migrate SDL2 API calls to SDL3 equivalents (event constants, function names, data types)
  • Add explicit text input initialization with SDL_StartTextInput/SDL_StopTextInput

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
flake.nix Updates Nix dependencies from SDL2 to SDL3 packages and removes legacy nixpkgs-24_05 input
build.zig Updates build configuration to link SDL3 libraries and use SDL3 environment variables
src/c.zig Updates C bindings from SDL2 to SDL3 headers, types, constants, and function names
src/main.zig Migrates application code to SDL3 API including initialization, event handling, rendering, and keyboard encoding
src/font.zig Updates font rendering to use SDL3_ttf API with new function signatures and return types

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main.zig
Comment on lines +835 to +836
if (key >= c.SDLK_A and key <= c.SDLK_Z) {
buf[0] = @as(u8, @intCast(key - c.SDLK_A + 1));
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Ctrl+key encoding logic now uses uppercase key constants (SDLK_A to SDLK_Z) instead of lowercase. This will only work if the key events report uppercase codes. In SDL3, key codes for letter keys may still report lowercase values depending on keyboard state, which would cause this condition to fail. Verify that SDL3 key events for letter keys report uppercase codes, or update the logic to handle both cases.

Suggested change
if (key >= c.SDLK_A and key <= c.SDLK_Z) {
buf[0] = @as(u8, @intCast(key - c.SDLK_A + 1));
var base: ?c.SDL_Keycode = null;
if (key >= c.SDLK_A and key <= c.SDLK_Z) {
base = c.SDLK_A;
} else if (key >= c.SDLK_a and key <= c.SDLK_z) {
base = c.SDLK_a;
}
if (base) |b| {
buf[0] = @as(u8, @intCast(key - b + 1));

Copilot uses AI. Check for mistakes.
Comment thread src/c.zig Outdated
Comment on lines 41 to 45
pub const SDL_PROP_WINDOW_CREATE_TITLE_STRING = c_import.SDL_PROP_WINDOW_CREATE_TITLE_STRING;
pub const SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER = c_import.SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER;
pub const SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER = c_import.SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER;
pub const SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER = c_import.SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER;

Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These SDL_PROP_WINDOW_CREATE_* constants are exported but never used in the codebase. The window creation in main.zig uses the direct SDL_CreateWindow function with positional parameters instead of the property-based API. Either use these constants with SDL_CreateWindowWithProperties, or remove them if they're not needed.

Suggested change
pub const SDL_PROP_WINDOW_CREATE_TITLE_STRING = c_import.SDL_PROP_WINDOW_CREATE_TITLE_STRING;
pub const SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER = c_import.SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER;
pub const SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER = c_import.SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER;
pub const SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER = c_import.SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER;

Copilot uses AI. Check for mistakes.
Comment thread src/font.zig Outdated
return error.FontLoadFailed;
}

log.info("Font cell dimensions: {d}x{d}", .{ cell_width, cell_height });
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new log statement outputs font cell dimensions at info level during initialization. This information would be more appropriate at debug level unless it's critical for troubleshooting production issues, as it will appear in normal operation logs.

Suggested change
log.info("Font cell dimensions: {d}x{d}", .{ cell_width, cell_height });
log.debug("Font cell dimensions: {d}x{d}", .{ cell_width, cell_height });

Copilot uses AI. Check for mistakes.
- Remove unused SDL_PROP_WINDOW_CREATE_* constants (not using property-based API)
- Change font cell dimensions log from info to debug level

Note: The Ctrl+key encoding suggestion was not applicable - SDL3 uses
uppercase key codes (SDLK_A-SDLK_Z) as canonical, with SDLK_a renamed
to SDLK_A. The original implementation was correct.
Copy link
Copy Markdown
Owner Author

@forketyfork forketyfork left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review comments addressed:

Removed unused SDL_PROP_WINDOW_CREATE_ constants* - These were from the property-based window creation API that we're not using. Removed to keep code clean.

Changed log level from info to debug - Font cell dimensions are now logged at debug level, appropriate for diagnostic information.

Ctrl+key encoding with lowercase - Not applicable to SDL3. The compilation error revealed that SDL3 canonically uses uppercase key codes (SDLK_A-SDLK_Z) for letter keys, with SDLK_a being a macro that's renamed to SDLK_A. The original implementation using uppercase is correct for SDL3.

Error when trying to use SDLK_a:

error: unable to translate macro: undefined identifier 'SDLK_a_renamed_SDLK_A'
pub const SDLK_a = @compileError("unable to translate macro: undefined identifier 'SDLK_a_renamed_SDLK_A'");

This is an SDL3 design change from SDL2 - letter keys now consistently use uppercase codes.

@forketyfork forketyfork merged commit 9229408 into main Dec 31, 2025
4 checks passed
@forketyfork forketyfork deleted the sdl3-migration branch December 31, 2025 12:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants