Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,19 @@ pub fn build(b: *std.Build) void {
.root_module = exe_mod,
});

exe.linkSystemLibrary("SDL2_ttf");
exe.linkSystemLibrary("SDL3");
exe.linkSystemLibrary("SDL3_ttf");
exe.linkLibC();

if (std.posix.getenv("SDL2_INCLUDE_PATH")) |sdl2_include| {
exe.addIncludePath(.{ .cwd_relative = sdl2_include });
if (std.posix.getenv("SDL3_INCLUDE_PATH")) |sdl3_include| {
exe.addIncludePath(.{ .cwd_relative = sdl3_include });
const lib_path = b.fmt("{s}/../lib", .{sdl3_include});
exe.addLibraryPath(.{ .cwd_relative = lib_path });
}
if (std.posix.getenv("SDL2_TTF_INCLUDE_PATH")) |sdl2_ttf_include| {
exe.addIncludePath(.{ .cwd_relative = sdl2_ttf_include });
if (std.posix.getenv("SDL3_TTF_INCLUDE_PATH")) |sdl3_ttf_include| {
exe.addIncludePath(.{ .cwd_relative = sdl3_ttf_include });
const ttf_lib_path = b.fmt("{s}/../lib", .{sdl3_ttf_include});
exe.addLibraryPath(.{ .cwd_relative = ttf_lib_path });
}

b.installArtifact(exe);
Expand Down
17 changes: 0 additions & 17 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 8 additions & 15 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nixpkgs-24_05.url = "github:NixOS/nixpkgs/nixos-24.05";
flake-utils.url = "github:numtide/flake-utils";
zig = {
url = "github:mitchellh/zig-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
};

outputs = { self, nixpkgs, nixpkgs-24_05, flake-utils, zig }:
outputs = { self, nixpkgs, flake-utils, zig }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
Expand All @@ -20,14 +19,8 @@
allowUnfree = true;
};
};
legacy = import nixpkgs-24_05 {
inherit system;
config = {
allowUnfree = true;
};
};
sdl2 = legacy.SDL2;
sdl2_ttf = legacy.SDL2_ttf;
sdl3 = pkgs.sdl3;
sdl3_ttf = pkgs.sdl3-ttf;
in
{
devShells.default = pkgs.mkShell {
Expand All @@ -39,18 +32,18 @@

buildInputs =
[
sdl2.dev
sdl2_ttf
sdl3.dev
sdl3_ttf
]
++ pkgs.lib.optionals pkgs.stdenv.hostPlatform.isDarwin [
pkgs.gawk
pkgs.gnused
];

shellHook = ''
export PKG_CONFIG_PATH="${sdl2}/lib/pkgconfig:${sdl2_ttf}/lib/pkgconfig:$PKG_CONFIG_PATH"
export SDL2_INCLUDE_PATH="${sdl2.dev}/include"
export SDL2_TTF_INCLUDE_PATH="${sdl2_ttf}/include"
export PKG_CONFIG_PATH="${sdl3}/lib/pkgconfig:${sdl3_ttf}/lib/pkgconfig:$PKG_CONFIG_PATH"
export SDL3_INCLUDE_PATH="${sdl3.dev}/include"
export SDL3_TTF_INCLUDE_PATH="${sdl3_ttf}/include"
echo "Architect development environment"
echo "Available commands: just --list"
''
Expand Down
49 changes: 24 additions & 25 deletions src/c.zig
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Minimal re-export layer that isolates C includes so the rest of the codebase
// can `@import("c.zig")` without pulling headers repeatedly.
const c_import = @cImport({
@cInclude("SDL2/SDL.h");
@cInclude("SDL2/SDL_ttf.h");
@cInclude("SDL3/SDL.h");
@cInclude("SDL3_ttf/SDL_ttf.h");
});

pub const SDL_Init = c_import.SDL_Init;
Expand All @@ -15,34 +15,31 @@ pub const SDL_SetRenderDrawColor = c_import.SDL_SetRenderDrawColor;
pub const SDL_RenderClear = c_import.SDL_RenderClear;
pub const SDL_RenderPresent = c_import.SDL_RenderPresent;
pub const SDL_RenderFillRect = c_import.SDL_RenderFillRect;
pub const SDL_RenderDrawRect = c_import.SDL_RenderDrawRect;
pub const SDL_RenderDrawLine = c_import.SDL_RenderDrawLine;
pub const SDL_RenderDrawPoint = c_import.SDL_RenderDrawPoint;
pub const SDL_RenderCopy = c_import.SDL_RenderCopy;
pub const SDL_RenderRect = c_import.SDL_RenderRect;
pub const SDL_RenderLine = c_import.SDL_RenderLine;
pub const SDL_RenderPoint = c_import.SDL_RenderPoint;
pub const SDL_RenderTexture = c_import.SDL_RenderTexture;
pub const SDL_SetRenderDrawBlendMode = c_import.SDL_SetRenderDrawBlendMode;
pub const SDL_QueryTexture = c_import.SDL_QueryTexture;
pub const SDL_GetTextureSize = c_import.SDL_GetTextureSize;
pub const SDL_CreateTextureFromSurface = c_import.SDL_CreateTextureFromSurface;
pub const SDL_DestroyTexture = c_import.SDL_DestroyTexture;
pub const SDL_FreeSurface = c_import.SDL_FreeSurface;
pub const SDL_DestroySurface = c_import.SDL_DestroySurface;
pub const SDL_GetError = c_import.SDL_GetError;
pub const SDL_PollEvent = c_import.SDL_PollEvent;
pub const SDL_Delay = c_import.SDL_Delay;
pub const SDL_StartTextInput = c_import.SDL_StartTextInput;
pub const SDL_StopTextInput = c_import.SDL_StopTextInput;

pub const SDL_INIT_VIDEO = c_import.SDL_INIT_VIDEO;
pub const SDL_WINDOW_SHOWN = c_import.SDL_WINDOW_SHOWN;
pub const SDL_WINDOWPOS_CENTERED = c_import.SDL_WINDOWPOS_CENTERED;
pub const SDL_RENDERER_ACCELERATED = c_import.SDL_RENDERER_ACCELERATED;
pub const SDL_BLENDMODE_BLEND = c_import.SDL_BLENDMODE_BLEND;
pub const SDL_QUIT = c_import.SDL_QUIT;
pub const SDL_KEYDOWN = c_import.SDL_KEYDOWN;
pub const SDL_TEXTINPUT = c_import.SDL_TEXTINPUT;
pub const SDL_MOUSEBUTTONDOWN = c_import.SDL_MOUSEBUTTONDOWN;
pub const SDL_MOUSEWHEEL = c_import.SDL_MOUSEWHEEL;
pub const SDL_EVENT_QUIT = c_import.SDL_EVENT_QUIT;
pub const SDL_EVENT_KEY_DOWN = c_import.SDL_EVENT_KEY_DOWN;
pub const SDL_EVENT_TEXT_INPUT = c_import.SDL_EVENT_TEXT_INPUT;
pub const SDL_EVENT_MOUSE_BUTTON_DOWN = c_import.SDL_EVENT_MOUSE_BUTTON_DOWN;
pub const SDL_EVENT_MOUSE_WHEEL = c_import.SDL_EVENT_MOUSE_WHEEL;

pub const SDL_HINT_RENDER_SCALE_QUALITY = c_import.SDL_HINT_RENDER_SCALE_QUALITY;
pub const SDL_SetHint = c_import.SDL_SetHint;
pub const SDL_SetTextureScaleMode = c_import.SDL_SetTextureScaleMode;
pub const SDL_ScaleModeLinear = c_import.SDL_ScaleModeLinear;
pub const SDL_SCALEMODE_LINEAR = c_import.SDL_SCALEMODE_LINEAR;

pub const SDLK_ESCAPE = c_import.SDLK_ESCAPE;
pub const SDLK_RETURN = c_import.SDLK_RETURN;
Expand All @@ -51,25 +48,27 @@ pub const SDLK_UP = c_import.SDLK_UP;
pub const SDLK_DOWN = c_import.SDLK_DOWN;
pub const SDLK_LEFT = c_import.SDLK_LEFT;
pub const SDLK_RIGHT = c_import.SDLK_RIGHT;
pub const SDLK_a = c_import.SDLK_a;
pub const SDLK_z = c_import.SDLK_z;
pub const KMOD_CTRL = c_import.KMOD_CTRL;
pub const SDLK_A = c_import.SDLK_A;
pub const SDLK_Z = c_import.SDLK_Z;
pub const SDL_KMOD_CTRL = c_import.SDL_KMOD_CTRL;

pub const TTF_Init = c_import.TTF_Init;
pub const TTF_Quit = c_import.TTF_Quit;
pub const TTF_OpenFont = c_import.TTF_OpenFont;
pub const TTF_CloseFont = c_import.TTF_CloseFont;
pub const TTF_RenderText_Blended = c_import.TTF_RenderText_Blended;
pub const TTF_RenderGlyph_Blended = c_import.TTF_RenderGlyph_Blended;
pub const TTF_SizeText = c_import.TTF_SizeText;
pub const TTF_GetError = c_import.TTF_GetError;
pub const TTF_GetStringSize = c_import.TTF_GetStringSize;

pub const SDL_Event = c_import.SDL_Event;
pub const SDL_FRect = c_import.SDL_FRect;
pub const SDL_Rect = c_import.SDL_Rect;
pub const SDL_FColor = c_import.SDL_FColor;
pub const SDL_Color = c_import.SDL_Color;
pub const SDL_Renderer = c_import.SDL_Renderer;
pub const SDL_Window = c_import.SDL_Window;
pub const SDL_Texture = c_import.SDL_Texture;
pub const SDL_Surface = c_import.SDL_Surface;
pub const SDL_Keysym = c_import.SDL_Keysym;
pub const SDL_Keycode = c_import.SDL_Keycode;
pub const SDL_Keymod = c_import.SDL_Keymod;
pub const TTF_Font = c_import.TTF_Font;
40 changes: 23 additions & 17 deletions src/font.zig
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,20 @@ pub const Font = struct {
} || std.mem.Allocator.Error;

pub fn init(allocator: std.mem.Allocator, renderer: *c.SDL_Renderer, font_path: [*:0]const u8, size: c_int) InitError!Font {
const font = c.TTF_OpenFont(font_path, size) orelse {
log.err("TTF_OpenFont failed: {s}", .{c.TTF_GetError()});
const font = c.TTF_OpenFont(font_path, @floatFromInt(size)) orelse {
log.err("TTF_OpenFont failed: {s}", .{c.SDL_GetError()});
return error.FontLoadFailed;
};

var cell_width: c_int = 0;
var cell_height: c_int = 0;
_ = c.TTF_SizeText(font, "M", &cell_width, &cell_height);
if (!c.TTF_GetStringSize(font, "M", 1, &cell_width, &cell_height)) {
log.err("TTF_GetStringSize failed: {s}", .{c.SDL_GetError()});
c.TTF_CloseFont(font);
return error.FontLoadFailed;
}

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

return Font{
.font = font,
Expand Down Expand Up @@ -67,18 +73,18 @@ pub const Font = struct {
return err;
};

var tex_width: c_int = 0;
var tex_height: c_int = 0;
_ = c.SDL_QueryTexture(texture, null, null, &tex_width, &tex_height);
var tex_width_f: f32 = 0;
var tex_height_f: f32 = 0;
_ = c.SDL_GetTextureSize(texture, &tex_width_f, &tex_height_f);

const dest_rect = c.SDL_Rect{
.x = x,
.y = y,
.w = target_width,
.h = target_height,
const dest_rect = c.SDL_FRect{
.x = @floatFromInt(x),
.y = @floatFromInt(y),
.w = @floatFromInt(target_width),
.h = @floatFromInt(target_height),
};

_ = c.SDL_RenderCopy(self.renderer, texture, null, &dest_rect);
_ = c.SDL_RenderTexture(self.renderer, texture, null, &dest_rect);
}

fn getGlyphTexture(self: *Font, codepoint: u21, fg_color: c.SDL_Color) RenderGlyphError!*c.SDL_Texture {
Expand All @@ -95,7 +101,7 @@ pub const Font = struct {
// others), then keep a texture keyed by codepoint+color for reuse.
const surface = if (codepoint < 0x10000) blk: {
break :blk c.TTF_RenderGlyph_Blended(self.font, @intCast(codepoint), fg_color) orelse {
log.debug("TTF_RenderGlyph_Blended failed for U+{X:0>4}: {s}", .{ codepoint, c.TTF_GetError() });
log.debug("TTF_RenderGlyph_Blended failed for U+{X:0>4}: {s}", .{ codepoint, c.SDL_GetError() });
return error.GlyphRenderFailed;
};
} else blk: {
Expand All @@ -106,19 +112,19 @@ pub const Font = struct {
@memcpy(text_buf[0..len], utf8_buf[0..len]);
text_buf[len] = 0;

break :blk c.TTF_RenderText_Blended(self.font, @ptrCast(&text_buf), fg_color) orelse {
log.debug("TTF_RenderText_Blended failed for U+{X:0>4}: {s}", .{ codepoint, c.TTF_GetError() });
break :blk c.TTF_RenderText_Blended(self.font, @ptrCast(&text_buf), len, fg_color) orelse {
log.debug("TTF_RenderText_Blended failed for U+{X:0>4}: {s}", .{ codepoint, c.SDL_GetError() });
return error.GlyphRenderFailed;
};
};
defer c.SDL_FreeSurface(surface);
defer c.SDL_DestroySurface(surface);

const texture = c.SDL_CreateTextureFromSurface(self.renderer, surface) orelse {
log.err("SDL_CreateTextureFromSurface failed: {s}", .{c.SDL_GetError()});
return error.TextureCreationFailed;
};

_ = c.SDL_SetTextureScaleMode(texture, c.SDL_ScaleModeLinear);
_ = c.SDL_SetTextureScaleMode(texture, c.SDL_SCALEMODE_LINEAR);

try self.glyph_cache.put(key, texture);
return texture;
Expand Down
Loading