diff options
29 files changed, 1093 insertions, 452 deletions
diff --git a/src/main.zig b/src/main.zig index 6a10921..30add69 100644 --- a/src/main.zig +++ b/src/main.zig @@ -98,14 +98,13 @@ pub fn main() !void { // Initialise SFML //-------------------------------------------------------------------------- - var window = try sf.RenderWindow.create(.{ .x = constants.ScreenWidth, .y = constants.ScreenHeight }, 32, "zirc", sf.window.Style.none); + var window = try sf.RenderWindow.create(.{ .x = constants.ScreenWidth, .y = constants.ScreenHeight }, 32, "zirc", sf.window.Style.none, null); defer window.destroy(); window.setFramerateLimit(40); - // TODO: implement this in the SFML wrapper and make a PR - sf.c.sfRenderWindow_setMouseCursorGrabbed(window.ptr, 1); - sf.c.sfRenderWindow_setMouseCursorVisible(window.ptr, 0); + window.setMouseCursorGrabbed(true); + window.setMouseCursorVisible(false); // Load the background skybox, really `skycylinder', and assign it to a // sprite -- it's set to repeating so that it goes on forever. We need to @@ -207,11 +206,11 @@ pub fn main() !void { try renderer.renderWorld( plyr, - window, + &window, objects_image, walls_image, surfaces_image, - rendered_surfaces_texture, + &rendered_surfaces_texture, rendered_surfaces_sprite, map, ); diff --git a/src/render.zig b/src/render.zig index 49595dd..4e9cf4b 100644 --- a/src/render.zig +++ b/src/render.zig @@ -47,11 +47,11 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type { pub fn renderWorld( self: *@This(), plyr: player.Player, - window: RenderWindow, + window: *RenderWindow, objects_image: Image, walls_image: Image, surfaces_image: Image, - rendered_surfaces_texture: Texture, + rendered_surfaces_texture: *Texture, rendered_surfaces_sprite: Sprite, map: level.Map, ) !void { @@ -69,7 +69,7 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type { // use the z_buffer to render sprites self.renderObjects(plyr, objects_image, map, &pixels); - try rendered_surfaces_texture.updateFromPixels(&pixels, null); + try rendered_surfaces_texture.updateFromPixels(pixels[0..], null); window.draw(rendered_surfaces_sprite, null); } diff --git a/src/sfml/audio/Music.zig b/src/sfml/audio/Music.zig index b02b620..d55a718 100644 --- a/src/sfml/audio/Music.zig +++ b/src/sfml/audio/Music.zig @@ -11,92 +11,92 @@ pub fn createFromFile(path: [:0]const u8) !Music { var music = sf.c.sfMusic_createFromFile(path); if (music == null) return sf.Error.resourceLoadingError; - return Music{ .ptr = music.? }; + return Music{ ._ptr = music.? }; } pub const initFromMemory = @compileError("Function is not implemented yet."); pub const initFromStream = @compileError("Function is not implemented yet."); /// Destroys this music object -pub fn destroy(self: Music) void { - sf.c.sfMusic_destroy(self.ptr); +pub fn destroy(self: *Music) void { + sf.c.sfMusic_destroy(self._ptr); } // Music control functions /// Plays the music -pub fn play(self: Music) void { - sf.c.sfMusic_play(self.ptr); +pub fn play(self: *Music) void { + sf.c.sfMusic_play(self._ptr); } /// Pauses the music -pub fn pause(self: Music) void { - sf.c.sfMusic_pause(self.ptr); +pub fn pause(self: *Music) void { + sf.c.sfMusic_pause(self._ptr); } /// Stops the music and resets the player position -pub fn stop(self: Music) void { - sf.c.sfMusic_stop(self.ptr); +pub fn stop(self: *Music) void { + sf.c.sfMusic_stop(self._ptr); } // Getters / Setters /// Gets the total duration of the music pub fn getDuration(self: Music) sf.Time { - return sf.Time.fromCSFML(sf.c.sfMusic_getDuration(self.ptr)); + return sf.Time._fromCSFML(sf.c.sfMusic_getDuration(self._ptr)); } /// Gets the current stream position of the music pub fn getPlayingOffset(self: Music) sf.Time { - return sf.Time.fromCSFML(sf.c.sfMusic_getPlayingOffset(self.ptr)); + return sf.Time._fromCSFML(sf.c.sfMusic_getPlayingOffset(self._ptr)); } /// Sets the current stream position of the music -pub fn setPlayingOffset(self: Music, offset: sf.Time) void { - sf.c.sfMusic_setPlayingOffset(self.ptr, offset.toCSFML()); +pub fn setPlayingOffset(self: *Music, offset: sf.Time) void { + sf.c.sfMusic_setPlayingOffset(self._ptr, offset._toCSFML()); } /// Gets the loop points of the music pub fn getLoopPoints(self: Music) sf.TimeSpan { - return sf.TimeSpan.fromCSFML(sf.c.sfMusic_getLoopPoints(self.ptr)); + return sf.TimeSpan._fromCSFML(sf.c.sfMusic_getLoopPoints(self._ptr)); } /// Gets the loop points of the music -pub fn setLoopPoints(self: Music, span: sf.TimeSpan) void { - sf.c.sfMusic_setLoopPoints(self.ptr, span.toCSFML()); +pub fn setLoopPoints(self: *Music, span: sf.TimeSpan) void { + sf.c.sfMusic_setLoopPoints(self._ptr, span._toCSFML()); } /// Tells whether or not this stream is in loop mode pub fn getLoop(self: Music) bool { - return sf.c.sfMusic_getLoop(self.ptr) != 0; + return sf.c.sfMusic_getLoop(self._ptr) != 0; } /// Enable or disable auto loop -pub fn setLoop(self: Music, loop: bool) void { - sf.c.sfMusic_setLoop(self.ptr, if (loop) 1 else 0); +pub fn setLoop(self: *Music, loop: bool) void { + sf.c.sfMusic_setLoop(self._ptr, @boolToInt(loop)); } /// Sets the pitch of the music pub fn getPitch(self: Music) f32 { - return sf.c.sfMusic_getPitch(self.ptr); + return sf.c.sfMusic_getPitch(self._ptr); } /// Gets the pitch of the music -pub fn setPitch(self: Music, pitch: f32) void { - sf.c.sfMusic_setPitch(self.ptr, pitch); +pub fn setPitch(self: *Music, pitch: f32) void { + sf.c.sfMusic_setPitch(self._ptr, pitch); } /// Sets the volume of the music pub fn getVolume(self: Music) f32 { - return sf.c.sfMusic_getVolume(self.ptr); + return sf.c.sfMusic_getVolume(self._ptr); } /// Gets the volume of the music -pub fn setVolume(self: Music, volume: f32) void { - sf.c.sfMusic_setVolume(self.ptr, volume); +pub fn setVolume(self: *Music, volume: f32) void { + sf.c.sfMusic_setVolume(self._ptr, volume); } /// Gets the sample rate of this music pub fn getSampleRate(self: Music) usize { - return @intCast(usize, sf.c.sfMusic_getSampleRate(self.ptr)); + return @intCast(usize, sf.c.sfMusic_getSampleRate(self._ptr)); } /// Gets the channel count of the music pub fn getChannelCount(self: Music) usize { - return @intCast(usize, sf.c.sfMusic_getChannelCount(self.ptr)); + return @intCast(usize, sf.c.sfMusic_getChannelCount(self._ptr)); } pub const getStatus = @compileError("Function is not implemented yet."); @@ -108,4 +108,4 @@ pub const getMinDistance = @compileError("Function is not implemented yet."); pub const getAttenuation = @compileError("Function is not implemented yet."); /// Pointer to the csfml music -ptr: *sf.c.sfMusic, +_ptr: *sf.c.sfMusic, diff --git a/src/sfml/audio/Sound.zig b/src/sfml/audio/Sound.zig index 073aa5f..92acb46 100644 --- a/src/sfml/audio/Sound.zig +++ b/src/sfml/audio/Sound.zig @@ -14,7 +14,7 @@ pub fn create() !Sound { var sound = sf.c.sfSound_create(); if (sound == null) return sf.Error.nullptrUnknownReason; - return Sound{ .ptr = sound.? }; + return Sound{ ._ptr = sound.? }; } /// Inits a sound with a SoundBuffer object @@ -25,74 +25,74 @@ pub fn createFromBuffer(buffer: sf.SoundBuffer) !Sound { } /// Destroys this sound object -pub fn destroy(self: Sound) void { - sf.c.sfSound_destroy(self.ptr); +pub fn destroy(self: *Sound) void { + sf.c.sfSound_destroy(self._ptr); } // Sound control functions /// Plays the sound -pub fn play(self: Sound) void { - sf.c.sfSound_play(self.ptr); +pub fn play(self: *Sound) void { + sf.c.sfSound_play(self._ptr); } /// Pauses the sound -pub fn pause(self: Sound) void { - sf.c.sfSound_pause(self.ptr); +pub fn pause(self: *Sound) void { + sf.c.sfSound_pause(self._ptr); } /// Stops the sound and resets the player position -pub fn stop(self: Sound) void { - sf.c.sfSound_stop(self.ptr); +pub fn stop(self: *Sound) void { + sf.c.sfSound_stop(self._ptr); } // Getters / Setters /// Gets the buffer this sound is attached to pub fn getBuffer(self: Sound) ?sf.SoundBuffer { - var buf = sf.c.sfSound_getBuffer(self.ptr); + var buf = sf.c.sfSound_getBuffer(self._ptr); if (buf) |buffer| { - return .{ .ptr = buffer }; + return .{ ._ptr = buffer }; } else return null; } /// Sets the buffer this sound will play -pub fn setBuffer(self: Sound, buffer: sf.SoundBuffer) void { - sf.c.sfSound_setBuffer(self.ptr, buffer.ptr); +pub fn setBuffer(self: *Sound, buffer: sf.SoundBuffer) void { + sf.c.sfSound_setBuffer(self._ptr, buffer._ptr); } /// Gets the current playing offset of the sound pub fn getPlayingOffset(self: Sound) sf.Time { - return sf.Time.fromCSFML(sf.c.sfSound_getPlayingOffset(self.ptr)); + return sf.Time._fromCSFML(sf.c.sfSound_getPlayingOffset(self._ptr)); } /// Sets the current playing offset of the sound -pub fn setPlayingOffset(self: Sound, offset: sf.Time) void { - sf.c.sfSound_setPlayingOffset(self.ptr, offset.toCSFML()); +pub fn setPlayingOffset(self: *Sound, offset: sf.Time) void { + sf.c.sfSound_setPlayingOffset(self._ptr, offset._toCSFML()); } /// Tells whether or not this sound is in loop mode pub fn getLoop(self: Sound) bool { - return sf.c.sfSound_getLoop(self.ptr) != 0; + return sf.c.sfSound_getLoop(self._ptr) != 0; } /// Enable or disable auto loop -pub fn setLoop(self: Sound, loop: bool) void { - sf.c.sfSound_setLoop(self.ptr, if (loop) 1 else 0); +pub fn setLoop(self: *Sound, loop: bool) void { + sf.c.sfSound_setLoop(self._ptr, @boolToInt(loop)); } /// Sets the pitch of the sound pub fn getPitch(self: Sound) f32 { - return sf.c.sfSound_getPitch(self.ptr); + return sf.c.sfSound_getPitch(self._ptr); } /// Gets the pitch of the sound -pub fn setPitch(self: Sound, pitch: f32) void { - sf.c.sfSound_setPitch(self.ptr, pitch); +pub fn setPitch(self: *Sound, pitch: f32) void { + sf.c.sfSound_setPitch(self._ptr, pitch); } /// Sets the volume of the sound pub fn getVolume(self: Sound) f32 { - return sf.c.sfSound_getVolume(self.ptr); + return sf.c.sfSound_getVolume(self._ptr); } /// Gets the volume of the sound -pub fn setVolume(self: Sound, volume: f32) void { - sf.c.sfSound_setVolume(self.ptr, volume); +pub fn setVolume(self: *Sound, volume: f32) void { + sf.c.sfSound_setVolume(self._ptr, volume); } pub const getStatus = @compileError("Function is not implemented yet."); @@ -104,4 +104,4 @@ pub const getMinDistance = @compileError("Function is not implemented yet."); pub const getAttenuation = @compileError("Function is not implemented yet."); /// Pointer to the csfml sound -ptr: *sf.c.sfSound, +_ptr: *sf.c.sfSound, diff --git a/src/sfml/audio/SoundBuffer.zig b/src/sfml/audio/SoundBuffer.zig index 9727088..39ed082 100644 --- a/src/sfml/audio/SoundBuffer.zig +++ b/src/sfml/audio/SoundBuffer.zig @@ -10,56 +10,56 @@ pub fn createFromFile(path: [:0]const u8) !SoundBuffer { var sound = sf.c.sfSoundBuffer_createFromFile(path); if (sound == null) return sf.Error.resourceLoadingError; - return SoundBuffer{ .ptr = sound.? }; + return SoundBuffer{ ._ptr = sound.? }; } /// Creates a sound buffer from sample data pub fn createFromSamples(samples: []const i16, channel_count: usize, sample_rate: usize) !SoundBuffer { var sound = sf.c.sfSoundBuffer_createFromSamples(@ptrCast([*c]const c_short, samples.ptr), samples.len, @intCast(c_uint, channel_count), @intCast(c_uint, sample_rate)); if (sound == null) return sf.Error.resourceLoadingError; - return SoundBuffer{ .ptr = sound.? }; + return SoundBuffer{ ._ptr = sound.? }; } pub const initFromMemory = @compileError("Function is not implemented yet."); pub const initFromStream = @compileError("Function is not implemented yet."); /// Destroys this music object -pub fn destroy(self: SoundBuffer) void { - sf.c.sfSoundBuffer_destroy(self.ptr); +pub fn destroy(self: *SoundBuffer) void { + sf.c.sfSoundBuffer_destroy(self._ptr); } // Getters / Setters /// Gets the duration of the sound pub fn getDuration(self: SoundBuffer) sf.system.Time { - return sf.system.Time.fromCSFML(sf.c.sfSoundBuffer_getDuration(self.ptr)); + return sf.system.Time._fromCSFML(sf.c.sfSoundBuffer_getDuration(self._ptr)); } /// Gets the sample count of this sound pub fn getSampleCount(self: SoundBuffer) usize { - return @intCast(usize, sf.c.sfSoundBuffer_getSampleCount(self.ptr)); + return @intCast(usize, sf.c.sfSoundBuffer_getSampleCount(self._ptr)); } /// Gets the sample rate of this sound (n° of samples per second, often 44100) pub fn getSampleRate(self: SoundBuffer) usize { - return @intCast(usize, sf.c.sfSoundBuffer_getSampleRate(self.ptr)); + return @intCast(usize, sf.c.sfSoundBuffer_getSampleRate(self._ptr)); } /// Gets the channel count (2 is stereo for instance) pub fn getChannelCount(self: SoundBuffer) usize { - return @intCast(usize, sf.c.sfSoundBuffer_getChannelCount(self.ptr)); + return @intCast(usize, sf.c.sfSoundBuffer_getChannelCount(self._ptr)); } // Misc /// Save the sound buffer to an audio file pub fn saveToFile(self: SoundBuffer, path: [:0]const u8) !void { - if (sf.c.sfSoundBuffer_saveToFile(self.ptr, path) != 1) + if (sf.c.sfSoundBuffer_saveToFile(self._ptr, path) != 1) return sf.Error.savingInFileFailed; } /// Pointer to the csfml texture -ptr: *sf.c.sfSoundBuffer, +_ptr: *sf.c.sfSoundBuffer, test "sound buffer: sane getter and setters" { const std = @import("std"); diff --git a/src/sfml/graphics/BlendMode.zig b/src/sfml/graphics/BlendMode.zig new file mode 100644 index 0000000..d78d60d --- /dev/null +++ b/src/sfml/graphics/BlendMode.zig @@ -0,0 +1,92 @@ +//! Blending modes for drawing (for render states) + +// Enums +pub const Factor = enum(c_int) { + zero, + one, + srcColor, + oneMinusSrcColor, + dstColor, + oneMinusDstColor, + srcAlpha, + oneMinusSrcAlpha, + dstAlpha, + oneMinusDstAlpha +}; + +pub const Equation = enum(c_int) { + add, + subtract, + reverseSubtract +}; + +const BlendMode = @This(); + +// Preset blend modes +pub const BlendAlpha = BlendMode{ + .color_src_factor = .srcAlpha, + .color_dst_factor = .oneMinusSrcAlpha, + .color_equation = .add, + .alpha_src_factor = .one, + .alpha_dst_factor = .oneMinusSrcAlpha, + .alpha_equation = .add +}; + +pub const BlendAdd = BlendMode{ + .color_src_factor = .srcAlpha, + .color_dst_factor = .one, + .color_equation = .add, + .alpha_src_factor = .one, + .alpha_dst_factor = .one, + .alpha_equation = .add +}; + +pub const BlendMultiply = BlendMode{ + .color_src_factor = .dstColor, + .color_dst_factor = .zero, + .color_equation = .add, + .alpha_src_factor = .dstColor, + .alpha_dst_factor = .zero, + .alpha_equation = .add +}; + +pub const BlendMin = BlendMode{ + .color_src_factor = .one, + .color_dst_factor = .one, + .color_equation = .min, + .alpha_src_factor = .one, + .alpha_dst_factor = .one, + .alpha_equation = .min +}; + +pub const BlendMax = BlendMode{ + .color_src_factor = .one, + .color_dst_factor = .one, + .color_equation = .max, + .alpha_src_factor = .one, + .alpha_dst_factor = .one, + .alpha_equation = .max +}; + +pub const BlendNone = BlendMode{ + .color_src_factor = .one, + .color_dst_factor = .zero, + .color_equation = .add, + .alpha_src_factor = .one, + .alpha_dst_factor = .zero, + .alpha_equation = .add +}; + +const sfBlendMode = @import("../sfml_import.zig").c.sfBlendMode; +/// Bitcasts this blendmode to the csfml struct +/// For inner workings +pub fn _toCSFML(self: BlendMode) sfBlendMode { + return @bitCast(sfBlendMode, self); +} + +color_src_factor: Factor, +color_dst_factor: Factor, +color_equation: Equation, +alpha_src_factor: Factor, +alpha_dst_factor: Factor, +alpha_equation: Equation
\ No newline at end of file diff --git a/src/sfml/graphics/CircleShape.zig b/src/sfml/graphics/CircleShape.zig index b2759e5..ea66dcb 100644 --- a/src/sfml/graphics/CircleShape.zig +++ b/src/sfml/graphics/CircleShape.zig @@ -19,107 +19,129 @@ pub fn create(radius: f32) !CircleShape { sf.c.sfCircleShape_setFillColor(circle, sf.c.sfWhite); sf.c.sfCircleShape_setRadius(circle, radius); - return CircleShape{ .ptr = circle.? }; + return CircleShape{ ._ptr = circle.? }; } /// Destroys a circle shape -pub fn destroy(self: CircleShape) void { - sf.c.sfCircleShape_destroy(self.ptr); +pub fn destroy(self: *CircleShape) void { + sf.c.sfCircleShape_destroy(self._ptr); } // Draw function -pub fn sfDraw(self: CircleShape, window: sf.RenderWindow, states: ?*sf.c.sfRenderStates) void { - sf.c.sfRenderWindow_drawCircleShape(window.ptr, self.ptr, states); +pub fn sfDraw(self: CircleShape, window: anytype, states: ?*sf.c.sfRenderStates) void { + switch (@TypeOf(window)) { + sf.RenderWindow => sf.c.sfRenderWindow_drawCircleShape(window._ptr, self._ptr, states), + sf.RenderTexture => sf.c.sfRenderTexture_drawCircleShape(window._ptr, self._ptr, states), + else => @compileError("window must be a render target"), + } } // Getters/setters /// Gets the fill color of this circle shape pub fn getFillColor(self: CircleShape) sf.Color { - return sf.Color.fromCSFML(sf.c.sfCircleShape_getFillColor(self.ptr)); + return sf.Color._fromCSFML(sf.c.sfCircleShape_getFillColor(self._ptr)); } /// Sets the fill color of this circle shape -pub fn setFillColor(self: CircleShape, color: sf.Color) void { - sf.c.sfCircleShape_setFillColor(self.ptr, color.toCSFML()); +pub fn setFillColor(self: *CircleShape, color: sf.Color) void { + sf.c.sfCircleShape_setFillColor(self._ptr, color._toCSFML()); +} + +/// Gets the outline color of this circle shape +pub fn getOutlineColor(self: CircleShape) sf.Color { + return sf.Color._fromCSFML(sf.c.sfCircleShape_getOutlineColor(self._ptr)); +} +/// Sets the outline color of this circle shape +pub fn setOutlineColor(self: *CircleShape, color: sf.Color) void { + sf.c.sfCircleShape_setOutlineColor(self._ptr, color._toCSFML()); +} + +/// Gets the outline thickness of this circle shape +pub fn getOutlineThickness(self: CircleShape) f32 { + return sf.c.sfCircleShape_getOutlineThickness(self._ptr); +} +/// Sets the outline thickness of this circle shape +pub fn setOutlineThickness(self: *CircleShape, thickness: f32) void { + sf.c.sfCircleShape_setOutlineThickness(self._ptr, thickness); } /// Gets the radius of this circle shape pub fn getRadius(self: CircleShape) f32 { - return sf.c.sfCircleShape_getRadius(self.ptr); + return sf.c.sfCircleShape_getRadius(self._ptr); } /// Sets the radius of this circle shape -pub fn setRadius(self: CircleShape, radius: f32) void { - sf.c.sfCircleShape_setRadius(self.ptr, radius); +pub fn setRadius(self: *CircleShape, radius: f32) void { + sf.c.sfCircleShape_setRadius(self._ptr, radius); } /// Gets the position of this circle shape pub fn getPosition(self: CircleShape) sf.Vector2f { - return sf.Vector2f.fromCSFML(sf.c.sfCircleShape_getPosition(self.ptr)); + return sf.Vector2f._fromCSFML(sf.c.sfCircleShape_getPosition(self._ptr)); } /// Sets the position of this circle shape -pub fn setPosition(self: CircleShape, pos: sf.Vector2f) void { - sf.c.sfCircleShape_setPosition(self.ptr, pos.toCSFML()); +pub fn setPosition(self: *CircleShape, pos: sf.Vector2f) void { + sf.c.sfCircleShape_setPosition(self._ptr, pos._toCSFML()); } /// Adds the offset to this shape's position -pub fn move(self: CircleShape, offset: sf.Vector2f) void { - sf.c.sfCircleShape_move(self.ptr, offset.toCSFML()); +pub fn move(self: *CircleShape, offset: sf.Vector2f) void { + sf.c.sfCircleShape_move(self._ptr, offset._toCSFML()); } /// Gets the origin of this circle shape pub fn getOrigin(self: CircleShape) sf.Vector2f { - return sf.Vector2f.fromCSFML(sf.c.sfCircleShape_getOrigin(self.ptr)); + return sf.Vector2f._fromCSFML(sf.c.sfCircleShape_getOrigin(self._ptr)); } /// Sets the origin of this circle shape -pub fn setOrigin(self: CircleShape, origin: sf.Vector2f) void { - sf.c.sfCircleShape_setOrigin(self.ptr, origin.toCSFML()); +pub fn setOrigin(self: *CircleShape, origin: sf.Vector2f) void { + sf.c.sfCircleShape_setOrigin(self._ptr, origin._toCSFML()); } /// Gets the rotation of this circle shape pub fn getRotation(self: CircleShape) f32 { - return sf.c.sfCircleShape_getRotation(self.ptr); + return sf.c.sfCircleShape_getRotation(self._ptr); } /// Sets the rotation of this circle shape -pub fn setRotation(self: CircleShape, angle: f32) void { - sf.c.sfCircleShape_setRotation(self.ptr, angle); +pub fn setRotation(self: *CircleShape, angle: f32) void { + sf.c.sfCircleShape_setRotation(self._ptr, angle); } /// Rotates this shape by a given amount -pub fn rotate(self: CircleShape, angle: f32) void { - sf.c.sfCircleShape_rotate(self.ptr, angle); +pub fn rotate(self: *CircleShape, angle: f32) void { + sf.c.sfCircleShape_rotate(self._ptr, angle); } /// Gets the texture of this shape pub fn getTexture(self: CircleShape) ?sf.Texture { - const t = sf.c.sfCircleShape_getTexture(self.ptr); + const t = sf.c.sfCircleShape_getTexture(self._ptr); if (t) |tex| { - return sf.Texture{ .const_ptr = tex }; + return sf.Texture{ ._const_ptr = tex }; } else return null; } /// Sets the texture of this shape -pub fn setTexture(self: CircleShape, texture: ?sf.Texture) void { - var tex = if (texture) |t| t.get() else null; - sf.c.sfCircleShape_setTexture(self.ptr, tex, 0); +pub fn setTexture(self: *CircleShape, texture: ?sf.Texture) void { + var tex = if (texture) |t| t._get() else null; + sf.c.sfCircleShape_setTexture(self._ptr, tex, 0); } /// Gets the sub-rectangle of the texture that the shape will display pub fn getTextureRect(self: CircleShape) sf.FloatRect { - return sf.FloatRect.fromCSFML(sf.c.sfCircleShape_getTextureRect(self.ptr)); + return sf.FloatRect._fromCSFML(sf.c.sfCircleShape_getTextureRect(self._ptr)); } /// Sets the sub-rectangle of the texture that the shape will display -pub fn setTextureRect(self: CircleShape, rect: sf.FloatRect) void { - sf.c.sfCircleShape_getCircleRect(self.ptr, rect.toCSFML()); +pub fn setTextureRect(self: *CircleShape, rect: sf.FloatRect) void { + sf.c.sfCircleShape_getCircleRect(self._ptr, rect._toCSFML()); } /// Gets the bounds in the local coordinates system pub fn getLocalBounds(self: CircleShape) sf.FloatRect { - return sf.FloatRect.fromCSFML(sf.c.sfCircleShape_getLocalBounds(self.ptr)); + return sf.FloatRect._fromCSFML(sf.c.sfCircleShape_getLocalBounds(self._ptr)); } /// Gets the bounds in the global coordinates pub fn getGlobalBounds(self: CircleShape) sf.FloatRect { - return sf.FloatRect.fromCSFML(sf.c.sfCircleShape_getGlobalBounds(self.ptr)); + return sf.FloatRect._fromCSFML(sf.c.sfCircleShape_getGlobalBounds(self._ptr)); } /// Pointer to the csfml structure -ptr: *sf.c.sfCircleShape, +_ptr: *sf.c.sfCircleShape, test "circle shape: sane getters and setters" { const tst = @import("std").testing; @@ -128,14 +150,17 @@ test "circle shape: sane getters and setters" { defer circle.destroy(); circle.setFillColor(sf.Color.Yellow); + circle.setOutlineColor(sf.Color.Red); + circle.setOutlineThickness(3); circle.setRadius(50); circle.setRotation(15); circle.setPosition(.{ .x = 1, .y = 2 }); circle.setOrigin(.{ .x = 20, .y = 25 }); circle.setTexture(null); - // TODO : issue #2 try tst.expectEqual(sf.Color.Yellow, circle.getFillColor()); + try tst.expectEqual(sf.Color.Red, circle.getOutlineColor()); + try tst.expectEqual(@as(f32, 3), circle.getOutlineThickness()); try tst.expectEqual(@as(f32, 50), circle.getRadius()); try tst.expectEqual(@as(f32, 15), circle.getRotation()); try tst.expectEqual(sf.Vector2f{ .x = 1, .y = 2 }, circle.getPosition()); diff --git a/src/sfml/graphics/Font.zig b/src/sfml/graphics/Font.zig index 78bd5a6..ecc1a56 100644 --- a/src/sfml/graphics/Font.zig +++ b/src/sfml/graphics/Font.zig @@ -11,15 +11,41 @@ pub fn createFromFile(path: [:0]const u8) !Font { var font = sf.c.sfFont_createFromFile(path); if (font == null) return sf.Error.resourceLoadingError; - return Font{ .ptr = font.? }; + return Font{ ._ptr = font.? }; } /// Destroys a font -pub fn destroy(self: Font) void { - sf.c.sfFont_destroy(self.ptr); +pub fn destroy(self: *Font) void { + sf.c.sfFont_destroy(self._ptr); } +/// Gets the family name of this font +/// Normally, this is done through getInfo, but as info only contains this data, this makes more sense +pub fn getFamily(self: Font) [*:0]const u8 { + return sf.c.sfFont_getInfo(self._ptr).family; +} + +/// Gets the kerning offset of two glyphs +pub fn getKerning(self: Font, first: u32, second: u32, character_size: usize) f32 { + return sf.c.sfFont_getKerning(self._ptr, first, second, @intCast(c_uint, character_size)); +} + +/// Gets the default spacing between two lines +pub fn getLineSpacing(self: Font, character_size: usize) f32 { + return sf.c.sfFont_getLineSpacing(self._ptr, @intCast(c_uint, character_size)); +} + +/// Gets the vertical offset of the underline +pub fn getUnderlinePosition(self: Font, character_size: usize) f32 { + return sf.c.sfFont_getUnderlinePosition(self._ptr, @intCast(c_uint, character_size)); +} +/// Gets the underline thickness +pub fn getUnderlineThickness(self: Font, character_size: usize) f32 { + return sf.c.sfFont_getUnderlineThickness(self._ptr, @intCast(c_uint, character_size)); +} + +pub const getGlyph = @compileError("Function is not implemented yet."); pub const initFromMemory = @compileError("Function is not implemented yet."); pub const initFromStream = @compileError("Function is not implemented yet."); /// Pointer to the csfml font -ptr: *sf.c.sfFont, +_ptr: *sf.c.sfFont, diff --git a/src/sfml/graphics/Image.zig b/src/sfml/graphics/Image.zig index 8ddf8e3..61dd027 100644 --- a/src/sfml/graphics/Image.zig +++ b/src/sfml/graphics/Image.zig @@ -15,10 +15,10 @@ const Image = @This(); /// Creates a new image pub fn create(size: sf.Vector2u, color: sf.Color) !Image { - var img = sf.c.sfImage_createFromColor(size.x, size.y, color.toCSFML()); + var img = sf.c.sfImage_createFromColor(size.x, size.y, color._toCSFML()); if (img == null) return sf.Error.nullptrUnknownReason; - return Image{ .ptr = img.? }; + return Image{ ._ptr = img.? }; } /// Creates an image from a pixel array @@ -31,7 +31,7 @@ pub fn createFromPixels(size: sf.Vector2u, pixels: []const sf.Color) !Image { if (img == null) return sf.Error.nullptrUnknownReason; - return Image{ .ptr = img.? }; + return Image{ ._ptr = img.? }; } /// Loads an image from a file @@ -39,17 +39,17 @@ pub fn createFromFile(path: [:0]const u8) !Image { var img = sf.c.sfImage_createFromFile(path); if (img == null) return sf.Error.resourceLoadingError; - return Image{ .ptr = img.? }; + return Image{ ._ptr = img.? }; } /// Destroys an image -pub fn destroy(self: Image) void { - sf.c.sfImage_destroy(self.ptr); +pub fn destroy(self: *Image) void { + sf.c.sfImage_destroy(self._ptr); } // Save an image to a file pub fn saveToFile(self: Image, path: [:0]const u8) !void { - if (sf.c.sfImage_saveToFile(self.ptr, path) != 1) + if (sf.c.sfImage_saveToFile(self._ptr, path) != 1) return sf.Error.savingInFileFailed; } @@ -60,24 +60,24 @@ pub fn getPixel(self: Image, pixel_pos: sf.Vector2u) sf.Color { const size = self.getSize(); assert(pixel_pos.x < size.x and pixel_pos.y < size.y); - return sf.Color.fromCSFML(sf.c.sfImage_getPixel(self.ptr, pixel_pos.x, pixel_pos.y)); + return sf.Color._fromCSFML(sf.c.sfImage_getPixel(self._ptr, pixel_pos.x, pixel_pos.y)); } /// Sets a pixel on this image (bounds are only checked in an assertion) -pub fn setPixel(self: Image, pixel_pos: sf.Vector2u, color: sf.Color) void { +pub fn setPixel(self: *Image, pixel_pos: sf.Vector2u, color: sf.Color) void { const size = self.getSize(); assert(pixel_pos.x < size.x and pixel_pos.y < size.y); - sf.c.sfImage_setPixel(self.ptr, pixel_pos.x, pixel_pos.y, color.toCSFML()); + sf.c.sfImage_setPixel(self._ptr, pixel_pos.x, pixel_pos.y, color._toCSFML()); } /// Gets the size of this image pub fn getSize(self: Image) sf.Vector2u { - const size = sf.c.sfImage_getSize(self.ptr); + const size = sf.c.sfImage_getSize(self._ptr); return sf.Vector2u{ .x = size.x, .y = size.y }; } /// Pointer to the csfml texture -ptr: *sf.c.sfImage, +_ptr: *sf.c.sfImage, test "image: sane getters and setters" { const tst = std.testing; diff --git a/src/sfml/graphics/RectangleShape.zig b/src/sfml/graphics/RectangleShape.zig index 34bb114..324199e 100644 --- a/src/sfml/graphics/RectangleShape.zig +++ b/src/sfml/graphics/RectangleShape.zig @@ -17,110 +17,131 @@ pub fn create(size: sf.Vector2f) !RectangleShape { return sf.Error.nullptrUnknownReason; sf.c.sfRectangleShape_setFillColor(rect, sf.c.sfWhite); - sf.c.sfRectangleShape_setSize(rect, size.toCSFML()); + sf.c.sfRectangleShape_setSize(rect, size._toCSFML()); - return RectangleShape{ .ptr = rect.? }; + return RectangleShape{ ._ptr = rect.? }; } /// Destroys a rectangle shape -pub fn destroy(self: RectangleShape) void { - sf.c.sfRectangleShape_destroy(self.ptr); +pub fn destroy(self: *RectangleShape) void { + sf.c.sfRectangleShape_destroy(self._ptr); } // Draw function -pub fn sfDraw(self: RectangleShape, window: sf.RenderWindow, states: ?*sf.c.sfRenderStates) void { - sf.c.sfRenderWindow_drawRectangleShape(window.ptr, self.ptr, states); +pub fn sfDraw(self: RectangleShape, window: anytype, states: ?*sf.c.sfRenderStates) void { + switch (@TypeOf(window)) { + sf.RenderWindow => sf.c.sfRenderWindow_drawRectangleShape(window._ptr, self._ptr, states), + sf.RenderTexture => sf.c.sfRenderTexture_drawRectangleShape(window._ptr, self._ptr, states), + else => @compileError("window must be a render target"), + } } // Getters/setters /// Gets the fill color of this rectangle shape pub fn getFillColor(self: RectangleShape) sf.Color { - return sf.Color.fromCSFML(sf.c.sfRectangleShape_getFillColor(self.ptr)); + return sf.Color._fromCSFML(sf.c.sfRectangleShape_getFillColor(self._ptr)); } /// Sets the fill color of this rectangle shape -pub fn setFillColor(self: RectangleShape, color: sf.Color) void { - sf.c.sfRectangleShape_setFillColor(self.ptr, color.toCSFML()); +pub fn setFillColor(self: *RectangleShape, color: sf.Color) void { + sf.c.sfRectangleShape_setFillColor(self._ptr, color._toCSFML()); +} + +/// Gets the outline color of this rectangle shape +pub fn getOutlineColor(self: RectangleShape) sf.Color { + return sf.Color._fromCSFML(sf.c.sfRectangleShape_getOutlineColor(self._ptr)); +} +/// Sets the outline color of this rectangle shape +pub fn setOutlineColor(self: *RectangleShape, color: sf.Color) void { + sf.c.sfRectangleShape_setOutlineColor(self._ptr, color._toCSFML()); +} + +/// Gets the outline thickness of this rectangle shape +pub fn getOutlineThickness(self: RectangleShape) f32 { + return sf.c.sfRectangleShape_getOutlineThickness(self._ptr); +} +/// Sets the outline thickness of this rectangle shape +pub fn setOutlineThickness(self: *RectangleShape, thickness: f32) void { + sf.c.sfRectangleShape_setOutlineThickness(self._ptr, thickness); } /// Gets the size of this rectangle shape pub fn getSize(self: RectangleShape) sf.Vector2f { - return sf.Vector2f.fromCSFML(sf.c.sfRectangleShape_getSize(self.ptr)); + return sf.Vector2f._fromCSFML(sf.c.sfRectangleShape_getSize(self._ptr)); } /// Sets the size of this rectangle shape -pub fn setSize(self: RectangleShape, size: sf.Vector2f) void { - sf.c.sfRectangleShape_setSize(self.ptr, size.toCSFML()); +pub fn setSize(self: *RectangleShape, size: sf.Vector2f) void { + sf.c.sfRectangleShape_setSize(self._ptr, size._toCSFML()); } /// Gets the position of this rectangle shape pub fn getPosition(self: RectangleShape) sf.Vector2f { - return sf.Vector2f.fromCSFML(sf.c.sfRectangleShape_getPosition(self.ptr)); + return sf.Vector2f._fromCSFML(sf.c.sfRectangleShape_getPosition(self._ptr)); } /// Sets the position of this rectangle shape -pub fn setPosition(self: RectangleShape, pos: sf.Vector2f) void { - sf.c.sfRectangleShape_setPosition(self.ptr, pos.toCSFML()); +pub fn setPosition(self: *RectangleShape, pos: sf.Vector2f) void { + sf.c.sfRectangleShape_setPosition(self._ptr, pos._toCSFML()); } /// Adds the offset to this shape's position -pub fn move(self: RectangleShape, offset: sf.Vector2f) void { - sf.c.sfRectangleShape_move(self.ptr, offset.toCSFML()); +pub fn move(self: *RectangleShape, offset: sf.Vector2f) void { + sf.c.sfRectangleShape_move(self._ptr, offset._toCSFML()); } /// Gets the origin of this rectangle shape pub fn getOrigin(self: RectangleShape) sf.Vector2f { - return sf.Vector2f.fromCSFML(sf.c.sfRectangleShape_getOrigin(self.ptr)); + return sf.Vector2f._fromCSFML(sf.c.sfRectangleShape_getOrigin(self._ptr)); } /// Sets the origin of this rectangle shape -pub fn setOrigin(self: RectangleShape, origin: sf.Vector2f) void { - sf.c.sfRectangleShape_setOrigin(self.ptr, origin.toCSFML()); +pub fn setOrigin(self: *RectangleShape, origin: sf.Vector2f) void { + sf.c.sfRectangleShape_setOrigin(self._ptr, origin._toCSFML()); } /// Gets the rotation of this rectangle shape pub fn getRotation(self: RectangleShape) f32 { - return sf.c.sfRectangleShape_getRotation(self.ptr); + return sf.c.sfRectangleShape_getRotation(self._ptr); } /// Sets the rotation of this rectangle shape -pub fn setRotation(self: RectangleShape, angle: f32) void { - sf.c.sfRectangleShape_setRotation(self.ptr, angle); +pub fn setRotation(self: *RectangleShape, angle: f32) void { + sf.c.sfRectangleShape_setRotation(self._ptr, angle); } /// Rotates this shape by a given amount -pub fn rotate(self: RectangleShape, angle: f32) void { - sf.c.sfRectangleShape_rotate(self.ptr, angle); +pub fn rotate(self: *RectangleShape, angle: f32) void { + sf.c.sfRectangleShape_rotate(self._ptr, angle); } /// Gets the texture of this shape pub fn getTexture(self: RectangleShape) ?sf.Texture { - const t = sf.c.sfRectangleShape_getTexture(self.ptr); + const t = sf.c.sfRectangleShape_getTexture(self._ptr); if (t) |tex| { - return sf.Texture{ .const_ptr = tex }; - } else - return null; + return sf.Texture{ ._const_ptr = tex }; + } else return null; } /// Sets the texture of this shape -pub fn setTexture(self: RectangleShape, texture: ?sf.Texture) void { - var tex = if (texture) |t| t.get() else null; - sf.c.sfRectangleShape_setTexture(self.ptr, tex, 0); +pub fn setTexture(self: *RectangleShape, texture: ?sf.Texture) void { + var tex = if (texture) |t| t._get() else null; + sf.c.sfRectangleShape_setTexture(self._ptr, tex, 0); } /// Gets the sub-rectangle of the texture that the shape will display pub fn getTextureRect(self: RectangleShape) sf.FloatRect { - return sf.FloatRect.fromCSFML(sf.c.sfRectangleShape_getTextureRect(self.ptr)); + return sf.FloatRect._fromCSFML(sf.c.sfRectangleShape_getTextureRect(self._ptr)); } /// Sets the sub-rectangle of the texture that the shape will display -pub fn setTextureRect(self: RectangleShape, rect: sf.FloatRect) void { - sf.c.sfRectangleShape_getTextureRect(self.ptr, rect.toCSFML()); +pub fn setTextureRect(self: *RectangleShape, rect: sf.FloatRect) void { + sf.c.sfRectangleShape_getTextureRect(self._ptr, rect._toCSFML()); } /// Gets the bounds in the local coordinates system pub fn getLocalBounds(self: RectangleShape) sf.FloatRect { - return sf.FloatRect.fromCSFML(sf.c.sfRectangleShape_getLocalBounds(self.ptr)); + return sf.FloatRect._fromCSFML(sf.c.sfRectangleShape_getLocalBounds(self._ptr)); } /// Gets the bounds in the global coordinates pub fn getGlobalBounds(self: RectangleShape) sf.FloatRect { - return sf.FloatRect.fromCSFML(sf.c.sfRectangleShape_getGlobalBounds(self.ptr)); + return sf.FloatRect._fromCSFML(sf.c.sfRectangleShape_getGlobalBounds(self._ptr)); } /// Pointer to the csfml structure -ptr: *sf.c.sfRectangleShape, +_ptr: *sf.c.sfRectangleShape, test "rectangle shape: sane getters and setters" { const tst = @import("std").testing; @@ -131,13 +152,17 @@ test "rectangle shape: sane getters and setters" { try tst.expectEqual(sf.Vector2f{ .x = 30, .y = 50 }, rect.getSize()); rect.setFillColor(sf.Color.Yellow); + rect.setOutlineColor(sf.Color.Red); + rect.setOutlineThickness(3); rect.setSize(.{ .x = 15, .y = 510 }); rect.setRotation(15); rect.setPosition(.{ .x = 1, .y = 2 }); rect.setOrigin(.{ .x = 20, .y = 25 }); - rect.setTexture(null); //Weirdly, getTexture if texture wasn't set gives a wrong pointer + rect.setTexture(null); //Weirdly, getTexture if texture wasn't set gives a wrong pointer try tst.expectEqual(sf.Color.Yellow, rect.getFillColor()); + try tst.expectEqual(sf.Color.Red, rect.getOutlineColor()); + try tst.expectEqual(@as(f32, 3), rect.getOutlineThickness()); try tst.expectEqual(sf.Vector2f{ .x = 15, .y = 510 }, rect.getSize()); try tst.expectEqual(@as(f32, 15), rect.getRotation()); try tst.expectEqual(sf.Vector2f{ .x = 1, .y = 2 }, rect.getPosition()); diff --git a/src/sfml/graphics/RenderStates.zig b/src/sfml/graphics/RenderStates.zig new file mode 100644 index 0000000..e7234ae --- /dev/null +++ b/src/sfml/graphics/RenderStates.zig @@ -0,0 +1,20 @@ +//! Defines settings for drawing things on a target + +const sf = struct { + pub usingnamespace @import("../sfml.zig"); + pub usingnamespace sf.graphics; +}; + +blend_mode: sf.BlendMode = sf.BlendMode.BlendAlpha, +//transform: null, // TODO: implement transforms (#25) +texture: ?sf.Texture = null, +shader: ?sf.Shader = null, + +pub fn _toCSFML(self: @This()) sf.c.sfRenderStates { + return .{ + .blendMode = self.blend_mode._toCSFML(), + .transform = .{ .matrix = .{ 1, 0, 0, 0, 1, 0, 0, 0, 1} }, + .texture = if (self.texture) |t| t._get() else null, + .shader = if (self.shader) |s| s._ptr else null + }; +}
\ No newline at end of file diff --git a/src/sfml/graphics/RenderTexture.zig b/src/sfml/graphics/RenderTexture.zig new file mode 100644 index 0000000..70b93ba --- /dev/null +++ b/src/sfml/graphics/RenderTexture.zig @@ -0,0 +1,177 @@ +//! Target for off-screen 2D rendering into a texture. + +const sf = struct { + pub usingnamespace @import("../sfml.zig"); + pub usingnamespace sf.system; + pub usingnamespace sf.graphics; +}; + +const RenderTexture = @This(); + +// Constructor/destructor + +/// Inits a render texture with a size (use createWithDepthBuffer if you want a depth buffer) +pub fn create(size: sf.Vector2u) !RenderTexture { + var rtex = sf.c.sfRenderTexture_create(size.x, size.y, 0); //0 means no depth buffer + + if (rtex) |t| { + return RenderTexture{ ._ptr = t }; + } else return sf.Error.nullptrUnknownReason; +} +/// Inits a render texture with a size, it will have a depth buffer +pub fn createWithDepthBuffer(size: sf.Vector2u) !RenderTexture { + var rtex = sf.c.sfRenderTexture_create(size.x, size.y, 1); + + if (rtex) |t| { + return .{ ._ptr = t }; + } else return sf.Error.nullptrUnknownReason; +} + +/// Destroys this render texture +pub fn destroy(self: *RenderTexture) void { + sf.c.sfRenderTexture_destroy(self._ptr); +} + +// Drawing functions + +/// Clears the drawing target with a color +pub fn clear(self: *RenderTexture, color: sf.Color) void { + sf.c.sfRenderTexture_clear(self._ptr, color._toCSFML()); +} + +/// Updates the texture with what has been drawn on the render area +pub fn display(self: *RenderTexture) void { + sf.c.sfRenderTexture_display(self._ptr); +} + +/// Draw something on the texture (won't be visible until display is called) +/// Object must have a sfDraw function (look at CircleShape for reference) +/// You can pass a render state or null for default +pub fn draw(self: *RenderTexture, to_draw: anytype, states: ?sf.RenderStates) void { + const T = @TypeOf(to_draw); + if (comptime @import("std").meta.trait.hasFn("sfDraw")(T)) { + // Inline call of object's draw function + if (states) |s| { + var cstates = s._toCSFML(); + @call(.{ .modifier = .always_inline }, T.sfDraw, .{ to_draw, self.*, &cstates }); + } else + @call(.{ .modifier = .always_inline }, T.sfDraw, .{ to_draw, self.*, null }); + // to_draw.sfDraw(self, states); + } else @compileError("You must provide a drawable object (struct with \"sfDraw\" method)."); +} + +/// Gets a const reference to the target texture (the reference doesn't change) +pub fn getTexture(self: RenderTexture) sf.Texture { + const tex = sf.c.sfRenderTexture_getTexture(self._ptr); + return sf.Texture{ ._const_ptr = tex.? }; +} + +// Texture related stuff + +/// Generates a mipmap for the current texture data, returns true if the operation succeeded +pub fn generateMipmap(self: *RenderTexture) bool { + return sf.c.sfRenderTexture_generateMipmap(self._ptr) != 0; +} + +/// Tells whether or not the texture is to be smoothed +pub fn isSmooth(self: RenderTexture) bool { + return sf.c.sfRenderTexture_isSmooth(self._ptr) != 0; +} +/// Enables or disables texture smoothing +pub fn setSmooth(self: *RenderTexture, smooth: bool) void { + sf.c.sfRenderTexture_setSmooth(self._ptr, @boolToInt(smooth)); +} + +/// Tells whether or not the texture should repeat when rendering outside its bounds +pub fn isRepeated(self: RenderTexture) bool { + return sf.c.sfRenderTexture_isRepeated(self._ptr) != 0; +} +/// Enables or disables texture repeating +pub fn setRepeated(self: *RenderTexture, repeated: bool) void { + sf.c.sfRenderTexture_setRepeated(self._ptr, @boolToInt(repeated)); +} + +/// Gets the size of this window +pub fn getSize(self: RenderTexture) sf.Vector2u { + return sf.Vector2u._fromCSFML(sf.c.sfRenderTexture_getSize(self._ptr)); +} + +// Target related stuff + +/// Gets the current view of the target +/// Unlike in SFML, you don't get a const pointer but a copy +pub fn getView(self: RenderTexture) sf.View { + return sf.View._fromCSFML(sf.c.sfRenderTexture_getView(self._ptr).?); +} +/// Gets the default view of this target +/// Unlike in SFML, you don't get a const pointer but a copy +pub fn getDefaultView(self: RenderTexture) sf.View { + return sf.View._fromCSFML(sf.c.sfRenderTexture_getDefaultView(self._ptr).?); +} +/// Sets the view of this target +pub fn setView(self: *RenderTexture, view: sf.View) void { + var cview = view._toCSFML(); + defer sf.c.sfView_destroy(cview); + sf.c.sfRenderTexture_setView(self._ptr, cview); +} +/// Gets the viewport of this target +pub fn getViewport(self: RenderTexture, view: sf.View) sf.IntRect { + return sf.IntRect._fromCSFML(sf.c.sfRenderTexture_getViewPort(self._ptr, view._ptr)); +} + +/// Convert a point from target coordinates to world coordinates, using the current view (or the specified view) +pub fn mapPixelToCoords(self: RenderTexture, pixel: sf.Vector2i, view: ?sf.View) sf.Vector2f { + if (view) |v| { + var cview = v._toCSFML(); + defer sf.c.sfView_destroy(cview); + return sf.Vector2f._fromCSFML(sf.c.sfRenderTexture_mapPixelToCoords(self._ptr, pixel._toCSFML(), cview)); + } else return sf.Vector2f._fromCSFML(sf.c.sfRenderTexture_mapPixelToCoords(self._ptr, pixel._toCSFML(), null)); +} +/// Convert a point from world coordinates to target coordinates, using the current view (or the specified view) +pub fn mapCoordsToPixel(self: RenderTexture, coords: sf.Vector2f, view: ?sf.View) sf.Vector2i { + if (view) |v| { + var cview = v._toCSFML(); + defer sf.c.sfView_destroy(cview); + return sf.Vector2i._fromCSFML(sf.c.sfRenderTexture_mapCoordsToPixel(self._ptr, coords._toCSFML(), cview)); + } else return sf.Vector2i._fromCSFML(sf.c.sfRenderTexture_mapCoordsToPixel(self._ptr, coords._toCSFML(), null)); +} + +/// Pointer to the csfml structure +_ptr: *sf.c.sfRenderTexture, + +test "rendertexture tests" { + const tst = @import("std").testing; + + var rentex = try RenderTexture.create(.{ .x = 10, .y = 10 }); + defer rentex.destroy(); + + rentex.setRepeated(true); + rentex.setSmooth(true); + + rentex.clear(sf.Color.Red); + { + var rect = try sf.RectangleShape.create(.{ .x = 5, .y = 5 }); + defer rect.destroy(); + + rect.setFillColor(sf.Color.Blue); + + rentex.draw(rect, null); + } + rentex.display(); + + _ = rentex.generateMipmap(); + + try tst.expect(rentex.isRepeated()); + try tst.expect(rentex.isSmooth()); + + const tex = rentex.getTexture(); + + try tst.expectEqual(sf.Vector2u{ .x = 10, .y = 10 }, tex.getSize()); + try tst.expectEqual(sf.Vector2u{ .x = 10, .y = 10 }, rentex.getSize()); + + var img = tex.copyToImage(); + defer img.destroy(); + + try tst.expectEqual(sf.Color.Blue, img.getPixel(.{ .x = 1, .y = 1 })); + try tst.expectEqual(sf.Color.Red, img.getPixel(.{ .x = 6, .y = 3 })); +} diff --git a/src/sfml/graphics/RenderWindow.zig b/src/sfml/graphics/RenderWindow.zig index dd6c7e3..a88adbf 100644 --- a/src/sfml/graphics/RenderWindow.zig +++ b/src/sfml/graphics/RenderWindow.zig @@ -4,6 +4,7 @@ const sf = struct { pub usingnamespace @import("../sfml.zig"); pub usingnamespace sf.system; pub usingnamespace sf.graphics; + pub usingnamespace sf.window; }; const RenderWindow = @This(); @@ -12,7 +13,7 @@ const RenderWindow = @This(); /// Inits a render window with a size, a bits per pixel (most put 32), a title and a style /// The window will have the default style -pub fn create(size: sf.Vector2u, bpp: usize, title: [:0]const u8, style: u32) !RenderWindow { +pub fn create(size: sf.Vector2u, bpp: usize, title: [:0]const u8, style: u32, settings: ?sf.ContextSettings) !RenderWindow { var ret: RenderWindow = undefined; var mode: sf.c.sfVideoMode = .{ @@ -21,17 +22,15 @@ pub fn create(size: sf.Vector2u, bpp: usize, title: [:0]const u8, style: u32) !R .bitsPerPixel = @intCast(c_uint, bpp), }; - var window = sf.c.sfRenderWindow_create(mode, @ptrCast([*c]const u8, title), style, null); + const c_settings = if (settings) |s| s._toCSFML() else null; + var window = sf.c.sfRenderWindow_create(mode, @ptrCast([*c]const u8, title), style, if (c_settings) |s| &s else null); if (window) |w| { - ret.ptr = w; - } else { - return sf.Error.windowCreationFailed; - } + ret._ptr = w; + } else return sf.Error.windowCreationFailed; return ret; } - /// Inits a render window with a size and a title /// The window will have the default style pub fn createDefault(size: sf.Vector2u, title: [:0]const u8) !RenderWindow { @@ -46,137 +45,162 @@ pub fn createDefault(size: sf.Vector2u, title: [:0]const u8) !RenderWindow { var window = sf.c.sfRenderWindow_create(mode, @ptrCast([*c]const u8, title), sf.window.Style.defaultStyle, null); if (window) |w| { - ret.ptr = w; - } else { - return sf.Error.windowCreationFailed; - } + ret._ptr = w; + } else return sf.Error.windowCreationFailed; return ret; } +/// Inits a rendering plane from a window handle. The handle can actually be to any drawing surface. +pub fn createFromHandle(handle: sf.WindowHandle, settings: ?sf.ContextSettings) !RenderWindow { + const c_settings = if (settings) |s| s._toCSFML() else null; + const window = sf.c.sfRenderWindow_createFromHandle(handle, if (c_settings) |s| &s else null); + + if (window) |w| { + return .{ ._ptr = w }; + } else return sf.Error.windowCreationFailed; +} /// Destroys this window object -pub fn destroy(self: RenderWindow) void { - sf.c.sfRenderWindow_destroy(self.ptr); +pub fn destroy(self: *RenderWindow) void { + sf.c.sfRenderWindow_destroy(self._ptr); } // Event related /// Returns true if this window is still open pub fn isOpen(self: RenderWindow) bool { - return sf.c.sfRenderWindow_isOpen(self.ptr) != 0; + return sf.c.sfRenderWindow_isOpen(self._ptr) != 0; } /// Closes this window -pub fn close(self: RenderWindow) void { - sf.c.sfRenderWindow_close(self.ptr); +pub fn close(self: *RenderWindow) void { + sf.c.sfRenderWindow_close(self._ptr); } /// Gets an event from the queue, returns null is theres none /// Use while on this to get all the events in your game loop -pub fn pollEvent(self: RenderWindow) ?sf.window.Event { +pub fn pollEvent(self: *RenderWindow) ?sf.window.Event { var event: sf.c.sfEvent = undefined; - if (sf.c.sfRenderWindow_pollEvent(self.ptr, &event) == 0) + if (sf.c.sfRenderWindow_pollEvent(self._ptr, &event) == 0) return null; // Skip sfEvtMouseWheelMoved to avoid sending mouseWheelScrolled twice if (event.type == sf.c.sfEvtMouseWheelMoved) { return self.pollEvent(); } - return sf.window.Event.fromCSFML(event); + return sf.window.Event._fromCSFML(event); } // Drawing functions /// Clears the drawing screen with a color -pub fn clear(self: RenderWindow, color: sf.Color) void { - sf.c.sfRenderWindow_clear(self.ptr, color.toCSFML()); +pub fn clear(self: *RenderWindow, color: sf.Color) void { + sf.c.sfRenderWindow_clear(self._ptr, color._toCSFML()); } /// Displays what has been drawn on the render area -pub fn display(self: RenderWindow) void { - sf.c.sfRenderWindow_display(self.ptr); +pub fn display(self: *RenderWindow) void { + sf.c.sfRenderWindow_display(self._ptr); } /// Draw something on the screen (won't be visible until display is called) /// Object must have a sfDraw function (look at CircleShape for reference) /// You can pass a render state or null for default -pub fn draw(self: RenderWindow, to_draw: anytype, states: ?*sf.c.sfRenderStates) void { +pub fn draw(self: *RenderWindow, to_draw: anytype, states: ?sf.RenderStates) void { const T = @TypeOf(to_draw); if (comptime @import("std").meta.trait.hasFn("sfDraw")(T)) { // Inline call of object's draw function - @call(.{ .modifier = .always_inline }, T.sfDraw, .{ to_draw, self, states }); + if (states) |s| { + var cstates = s._toCSFML(); + @call(.{ .modifier = .always_inline }, T.sfDraw, .{ to_draw, self.*, &cstates }); + } else + @call(.{ .modifier = .always_inline }, T.sfDraw, .{ to_draw, self.*, null }); // to_draw.sfDraw(self, states); } else @compileError("You must provide a drawable object (struct with \"sfDraw\" method)."); } // Getters/setters + /// Gets the current view of the window /// Unlike in SFML, you don't get a const pointer but a copy pub fn getView(self: RenderWindow) sf.View { - return sf.View.fromCSFML(sf.c.sfRenderWindow_getView(self.ptr).?); + return sf.View._fromCSFML(sf.c.sfRenderWindow_getView(self._ptr).?); } /// Gets the default view of this window /// Unlike in SFML, you don't get a const pointer but a copy pub fn getDefaultView(self: RenderWindow) sf.View { - return sf.View.fromCSFML(sf.c.sfRenderWindow_getDefaultView(self.ptr).?); + return sf.View._fromCSFML(sf.c.sfRenderWindow_getDefaultView(self._ptr).?); } /// Sets the view of this window -pub fn setView(self: RenderWindow, view: sf.View) void { - var cview = view.toCSFML(); +pub fn setView(self: *RenderWindow, view: sf.View) void { + var cview = view._toCSFML(); defer sf.c.sfView_destroy(cview); - sf.c.sfRenderWindow_setView(self.ptr, cview); + sf.c.sfRenderWindow_setView(self._ptr, cview); +} +/// Gets the viewport of this render target +pub fn getViewport(self: RenderWindow, view: sf.View) sf.IntRect { + return sf.IntRect._fromCSFML(sf.c.sfRenderWindow_getViewPort(self._ptr, view._ptr)); +} + +/// Set mouse cursor grabbing +pub fn setMouseCursorGrabbed(self : RenderWindow, grab : bool) void { + sf.c.sfRenderWindow_setMouseCursorGrabbed(self._ptr, if (grab) 1 else 0); +} + +/// Set mouse cursor visibility +pub fn setMouseCursorVisible(self : RenderWindow, visible : bool) void { + sf.c.sfRenderWindow_setMouseCursorVisible(self._ptr, if (visible) 1 else 0); } /// Gets the size of this window pub fn getSize(self: RenderWindow) sf.Vector2u { - return sf.Vector2u.fromCSFML(sf.c.sfRenderWindow_getSize(self.ptr)); + return sf.Vector2u._fromCSFML(sf.c.sfRenderWindow_getSize(self._ptr)); } /// Sets the size of this window -pub fn setSize(self: RenderWindow, size: sf.Vector2u) void { - sf.c.sfRenderWindow_setSize(self.ptr, size.toCSFML()); +pub fn setSize(self: *RenderWindow, size: sf.Vector2u) void { + sf.c.sfRenderWindow_setSize(self._ptr, size._toCSFML()); } /// Gets the position of this window pub fn getPosition(self: RenderWindow) sf.Vector2i { - return sf.Vector2i.fromCSFML(sf.c.sfRenderWindow_getPosition(self.ptr)); + return sf.Vector2i._fromCSFML(sf.c.sfRenderWindow_getPosition(self._ptr)); } /// Sets the position of this window -pub fn setPosition(self: RenderWindow, pos: sf.Vector2i) void { - sf.c.sfRenderWindow_setPosition(self.ptr, pos.toCSFML()); +pub fn setPosition(self: *RenderWindow, pos: sf.Vector2i) void { + sf.c.sfRenderWindow_setPosition(self._ptr, pos._toCSFML()); } // TODO : unicode title? /// Sets the title of this window -pub fn setTitle(self: RenderWindow, title: [:0]const u8) void { - sf.c.sfRenderWindow_setTitle(self.ptr, title); +pub fn setTitle(self: *RenderWindow, title: [:0]const u8) void { + sf.c.sfRenderWindow_setTitle(self._ptr, title); } /// Sets the windows's framerate limit -pub fn setFramerateLimit(self: RenderWindow, fps: c_uint) void { - sf.c.sfRenderWindow_setFramerateLimit(self.ptr, fps); +pub fn setFramerateLimit(self: *RenderWindow, fps: c_uint) void { + sf.c.sfRenderWindow_setFramerateLimit(self._ptr, fps); } /// Enables or disables vertical sync -pub fn setVerticalSyncEnabled(self: RenderWindow, enabled: bool) void { - sf.c.sfRenderWindow_setFramerateLimit(self.ptr, if (enabled) 1 else 0); +pub fn setVerticalSyncEnabled(self: *RenderWindow, enabled: bool) void { + sf.c.sfRenderWindow_setVerticalSyncEnabled(self._ptr, @boolToInt(enabled)); } /// Convert a point from target coordinates to world coordinates, using the current view (or the specified view) pub fn mapPixelToCoords(self: RenderWindow, pixel: sf.Vector2i, view: ?sf.View) sf.Vector2f { if (view) |v| { - var cview = v.toCSFML(); + var cview = v._toCSFML(); defer sf.c.sfView_destroy(cview); - return sf.Vector2f.fromCSFML(sf.c.sfRenderWindow_mapPixelToCoords(self.ptr, pixel.toCSFML(), cview)); - } else return sf.Vector2f.fromCSFML(sf.c.sfRenderWindow_mapPixelToCoords(self.ptr, pixel.toCSFML(), null)); + return sf.Vector2f._fromCSFML(sf.c.sfRenderWindow_mapPixelToCoords(self._ptr, pixel._toCSFML(), cview)); + } else return sf.Vector2f._fromCSFML(sf.c.sfRenderWindow_mapPixelToCoords(self._ptr, pixel._toCSFML(), null)); } - /// Convert a point from world coordinates to target coordinates, using the current view (or the specified view) pub fn mapCoordsToPixel(self: RenderWindow, coords: sf.Vector2f, view: ?sf.View) sf.Vector2i { if (view) |v| { - var cview = v.toCSFML(); + var cview = v._toCSFML(); defer sf.c.sfView_destroy(cview); - return sf.Vector2i.fromCSFML(sf.c.sfRenderWindow_mapCoordsToPixel(self.ptr, coords.toCSFML(), cview)); - } else return sf.Vector2i.fromCSFML(sf.c.sfRenderWindow_mapCoordsToPixel(self.ptr, coords.toCSFML(), null)); + return sf.Vector2i._fromCSFML(sf.c.sfRenderWindow_mapCoordsToPixel(self._ptr, coords._toCSFML(), cview)); + } else return sf.Vector2i._fromCSFML(sf.c.sfRenderWindow_mapCoordsToPixel(self._ptr, coords._toCSFML(), null)); } /// Pointer to the csfml structure -ptr: *sf.c.sfRenderWindow +_ptr: *sf.c.sfRenderWindow diff --git a/src/sfml/graphics/Shader.zig b/src/sfml/graphics/Shader.zig new file mode 100644 index 0000000..ea5072c --- /dev/null +++ b/src/sfml/graphics/Shader.zig @@ -0,0 +1,96 @@ +//! Shader class + +const sf = @import("../sfml.zig"); +const glsl = sf.graphics.glsl; + +const Shader = @This(); + +// Constructor/destructor + +/// Creates a shader object from shader files, you can omit some shader types by passing null +pub fn createFromFile( + vertex_shader_path: ?[:0]const u8, + geometry_shader_path: ?[:0]const u8, + fragment_shader_path: ?[:0]const u8 +) !Shader { + const shader = sf.c.sfShader_createFromFile( + if (vertex_shader_path) |vsp| @ptrCast([*c]const u8, vsp) else null, + if (geometry_shader_path) |gsp| @ptrCast([*c]const u8, gsp) else null, + if (fragment_shader_path) |fsp| @ptrCast([*c]const u8, fsp) else null + ); + if (shader) |s| { + return Shader{ ._ptr = s }; + } else return sf.Error.nullptrUnknownReason; +} +/// Create a shader object from glsl code as string, you can omit some shader types by passing null +pub fn createFromMemory( + vertex_shader: ?[:0]const u8, + geometry_shader: ?[:0]const u8, + fragment_shader: ?[:0]const u8 +) !Shader { + const shader = sf.c.sfShader_createFromMemory( + if (vertex_shader) |vs| @ptrCast([*c]const u8, vs) else null, + if (geometry_shader) |gs| @ptrCast([*c]const u8, gs) else null, + if (fragment_shader) |fs| @ptrCast([*c]const u8, fs) else null + ); + if (shader) |s| { + return Shader{ ._ptr = s }; + } else return sf.Error.nullptrUnknownReason; +} +/// Destroys this shader object +pub fn destroy(self: *Shader) void { + sf.c.sfShader_destroy(self._ptr); +} + +// Availability + +/// Checks whether or not shaders can be used in the system +pub fn isAvailable() bool { + return sf.c.sfShader_isAvailable(); +} +/// Checks whether or not geometry shaders can be used +pub fn isGeometryAvailable() bool { + return sf.c.sfShader_isAvailable(); +} + +const CurrentTextureT = struct{}; +/// Special value to pass to setUniform to have an uniform of the texture used for drawing +/// which cannot be known in advance +pub const CurrentTexture: CurrentTextureT = .{}; + +// Uniform + +/// Sets an uniform for the shader +/// Colors are vectors so if you want to pass a color use .toIVec4() or .toFVec4() +/// Pass CurrentTexture if you want to have the drawing texture as an uniform, which cannot be known in advance +pub fn setUniform(self: *Shader, name: [:0]const u8, value: anytype) void { + const T = @TypeOf(value); + switch (T) { + f32 => sf.c.sfShader_setFloatUniform(self._ptr, name, value), + c_int => sf.c.sfShader_setIntUniform(self._ptr, name, value), + bool => sf.c.sfShader_setBoolUniform(self._ptr, name, value), + glsl.FVec2 => sf.c.sfShader_setVec2Uniform(self._ptr, name, value._toCSFML()), + glsl.FVec3 => sf.c.sfShader_setVec3Uniform(self._ptr, name, value._toCSFML()), + glsl.FVec4 => sf.c.sfShader_setVec4Uniform(self._ptr, name, @bitCast(sf.c.sfGlslVec4, value)), + glsl.IVec2 => sf.c.sfShader_setIvec2Uniform(self._ptr, name, value._toCSFML()), + glsl.IVec3 => sf.c.sfShader_setIvec3Uniform(self._ptr, name, @bitCast(sf.c.sfGlslIvec3, value)), + glsl.IVec4 => sf.c.sfShader_setIvec4Uniform(self._ptr, name, @bitCast(sf.c.sfGlslIvec4, value)), + glsl.BVec2 => sf.c.sfShader_setBvec2Uniform(self._ptr, name, @bitCast(sf.c.sfGlslBvec2, value)), + glsl.BVec3 => sf.c.sfShader_setBvec3Uniform(self._ptr, name, @bitCast(sf.c.sfGlslBvec3, value)), + glsl.BVec4 => sf.c.sfShader_setBvec4Uniform(self._ptr, name, @bitCast(sf.c.sfGlslBvec4, value)), + glsl.Mat3 => sf.c.sfShader_setMat3Uniform(self._ptr, name, @ptrCast(*const sf.c.sfGlslMat3, @alignCast(4, &value))), + glsl.Mat4 => sf.c.sfShader_setMat4Uniform(self._ptr, name, @ptrCast(*const sf.c.sfGlslMat4, @alignCast(4, &value))), + sf.graphics.Texture => sf.c.sfShader_setTextureUniform(self._ptr, name, value._get()), + CurrentTextureT => sf.c.sfShader_setCurrentTextureUniform(self._ptr, name), + []const f32 => sf.c.sfShader_setFloatUniformArray(self._ptr, name, value.ptr, value.len), + []const glsl.FVec2 => sf.c.sfShader_setVec2UniformArray(self._ptr, name, @ptrCast(*sf.c.sfGlslVec2, value.ptr), value.len), + []const glsl.FVec3 => sf.c.sfShader_setVec3UniformArray(self._ptr, name, @ptrCast(*sf.c.sfGlslVec3, value.ptr), value.len), + []const glsl.FVec4 => sf.c.sfShader_setVec4UniformArray(self._ptr, name, @ptrCast(*sf.c.sfGlslVec4, value.ptr), value.len), + []const glsl.Mat3 => sf.c.sfShader_setMat3UniformArray(self._ptr, name, @ptrCast(*sf.c.sfGlslMat3, value.ptr), value.len), + []const glsl.Mat4 => sf.c.sfShader_setMat4UniformArray(self._ptr, name, @ptrCast(*sf.c.sfGlslVec4, value.ptr), value.len), + else => @compileError("Uniform of type \"" ++ @typeName(T) ++ "\" cannot be set inside shader.") + } +} + +/// Pointer to the CSFML structure +_ptr: *sf.c.sfShader
\ No newline at end of file diff --git a/src/sfml/graphics/Sprite.zig b/src/sfml/graphics/Sprite.zig index 4f24735..872c980 100644 --- a/src/sfml/graphics/Sprite.zig +++ b/src/sfml/graphics/Sprite.zig @@ -16,7 +16,7 @@ pub fn create() !Sprite { if (sprite == null) return sf.Error.nullptrUnknownReason; - return Sprite{ .ptr = sprite.? }; + return Sprite{ ._ptr = sprite.? }; } /// Inits a sprite with a texture @@ -25,103 +25,107 @@ pub fn createFromTexture(texture: sf.Texture) !Sprite { if (sprite == null) return sf.Error.nullptrUnknownReason; - sf.c.sfSprite_setTexture(sprite, texture.get(), 1); + sf.c.sfSprite_setTexture(sprite, texture._get(), 1); - return Sprite{ .ptr = sprite.? }; + return Sprite{ ._ptr = sprite.? }; } /// Destroys this sprite -pub fn destroy(self: Sprite) void { - sf.c.sfSprite_destroy(self.ptr); +pub fn destroy(self: *Sprite) void { + sf.c.sfSprite_destroy(self._ptr); } // Draw function -pub fn sfDraw(self: Sprite, window: sf.RenderWindow, states: ?*sf.c.sfRenderStates) void { - sf.c.sfRenderWindow_drawSprite(window.ptr, self.ptr, states); +pub fn sfDraw(self: Sprite, window: anytype, states: ?*sf.c.sfRenderStates) void { + switch (@TypeOf(window)) { + sf.RenderWindow => sf.c.sfRenderWindow_drawSprite(window._ptr, self._ptr, states), + sf.RenderTexture => sf.c.sfRenderTexture_drawSprite(window._ptr, self._ptr, states), + else => @compileError("window must be a render target"), + } } // Getters/setters /// Gets the position of this sprite pub fn getPosition(self: Sprite) sf.Vector2f { - return sf.Vector2f.fromCSFML(sf.c.sfSprite_getPosition(self.ptr)); + return sf.Vector2f._fromCSFML(sf.c.sfSprite_getPosition(self._ptr)); } /// Sets the position of this sprite -pub fn setPosition(self: Sprite, pos: sf.Vector2f) void { - sf.c.sfSprite_setPosition(self.ptr, pos.toCSFML()); +pub fn setPosition(self: *Sprite, pos: sf.Vector2f) void { + sf.c.sfSprite_setPosition(self._ptr, pos._toCSFML()); } /// Adds the offset to this shape's position -pub fn move(self: Sprite, offset: sf.Vector2f) void { - sf.c.sfSprite_move(self.ptr, offset.toCSFML()); +pub fn move(self: *Sprite, offset: sf.Vector2f) void { + sf.c.sfSprite_move(self._ptr, offset._toCSFML()); } /// Gets the scale of this sprite pub fn getScale(self: Sprite) sf.Vector2f { - return sf.Vector2f.fromCSFML(sf.c.sfSprite_getScale(self.ptr)); + return sf.Vector2f._fromCSFML(sf.c.sfSprite_getScale(self._ptr)); } /// Sets the scale of this sprite -pub fn setScale(self: Sprite, factor: sf.Vector2f) void { - sf.c.sfSprite_setScale(self.ptr, factor.toCSFML()); +pub fn setScale(self: *Sprite, factor: sf.Vector2f) void { + sf.c.sfSprite_setScale(self._ptr, factor._toCSFML()); } /// Scales this sprite -pub fn scale(self: Sprite, factor: sf.Vector2f) void { - sf.c.sfSprite_scale(self.ptr, factor.toCSFML()); +pub fn scale(self: *Sprite, factor: sf.Vector2f) void { + sf.c.sfSprite_scale(self._ptr, factor._toCSFML()); } /// Gets the origin of this sprite pub fn getOrigin(self: Sprite) sf.Vector2f { - return sf.Vector2f.fromCSFML(sf.c.sfSprite_getOrigin(self.ptr)); + return sf.Vector2f._fromCSFML(sf.c.sfSprite_getOrigin(self._ptr)); } /// Sets the origin of this sprite -pub fn setOrigin(self: Sprite, origin: sf.Vector2f) void { - sf.c.sfSprite_setOrigin(self.ptr, origin.toCSFML()); +pub fn setOrigin(self: *Sprite, origin: sf.Vector2f) void { + sf.c.sfSprite_setOrigin(self._ptr, origin._toCSFML()); } /// Gets the rotation of this sprite pub fn getRotation(self: Sprite) f32 { - return sf.c.sfSprite_getRotation(self.ptr); + return sf.c.sfSprite_getRotation(self._ptr); } /// Sets the rotation of this sprite -pub fn setRotation(self: Sprite, angle: f32) void { - sf.c.sfSprite_setRotation(self.ptr, angle); +pub fn setRotation(self: *Sprite, angle: f32) void { + sf.c.sfSprite_setRotation(self._ptr, angle); } /// Rotates this shape by a given amount -pub fn rotate(self: Sprite, angle: f32) void { - sf.c.sfSprite_rotate(self.ptr, angle); +pub fn rotate(self: *Sprite, angle: f32) void { + sf.c.sfSprite_rotate(self._ptr, angle); } /// Gets the color of this sprite pub fn getColor(self: Sprite) sf.Color { - return sf.Color.fromCSFML(sf.c.sfSprite_getColor(self.ptr)); + return sf.Color._fromCSFML(sf.c.sfSprite_getColor(self._ptr)); } /// Sets the color of this sprite -pub fn setColor(self: Sprite, color: sf.Color) void { - sf.c.sfSprite_setColor(self.ptr, color.toCSFML()); +pub fn setColor(self: *Sprite, color: sf.Color) void { + sf.c.sfSprite_setColor(self._ptr, color._toCSFML()); } /// Gets the texture of this shape pub fn getTexture(self: Sprite) ?sf.Texture { - const t = sf.c.sfSprite_getTexture(self.ptr); + const t = sf.c.sfSprite_getTexture(self._ptr); if (t) |tex| { - return sf.Texture{ .const_ptr = tex }; + return sf.Texture{ ._const_ptr = tex }; } else return null; } /// Sets this sprite's texture (the sprite will take the texture's dimensions) -pub fn setTexture(self: Sprite, texture: ?sf.Texture) void { - var tex = if (texture) |t| t.get() else null; - sf.c.sfSprite_setTexture(self.ptr, tex, 1); +pub fn setTexture(self: *Sprite, texture: ?sf.Texture) void { + var tex = if (texture) |t| t._get() else null; + sf.c.sfSprite_setTexture(self._ptr, tex, 1); } /// Gets the sub-rectangle of the texture that the sprite will display pub fn getTextureRect(self: Sprite) sf.IntRect { - return sf.IntRect.fromCSFML(sf.c.sfSprite_getTextureRect(self.ptr)); + return sf.IntRect._fromCSFML(sf.c.sfSprite_getTextureRect(self._ptr)); } /// Sets the sub-rectangle of the texture that the sprite will display -pub fn setTextureRect(self: Sprite, rect: sf.IntRect) void { - sf.c.sfSprite_setTextureRect(self.ptr, rect.toCSFML()); +pub fn setTextureRect(self: *Sprite, rect: sf.IntRect) void { + sf.c.sfSprite_setTextureRect(self._ptr, rect._toCSFML()); } /// Pointer to the csfml structure -ptr: *sf.c.sfSprite, +_ptr: *sf.c.sfSprite, test "sprite: sane getters and setters" { const tst = @import("std").testing; diff --git a/src/sfml/graphics/Text.zig b/src/sfml/graphics/Text.zig index caaefa5..b64a2f4 100644 --- a/src/sfml/graphics/Text.zig +++ b/src/sfml/graphics/Text.zig @@ -15,161 +15,165 @@ pub fn create() !Text { var text = sf.c.sfText_create(); if (text == null) return sf.Error.nullptrUnknownReason; - return Text{ .ptr = text.? }; + return Text{ ._ptr = text.? }; } /// Inits a text with content pub fn createWithText(string: [:0]const u8, font: sf.Font, character_size: usize) !Text { var text = sf.c.sfText_create(); if (text == null) return sf.Error.nullptrUnknownReason; - sf.c.sfText_setFont(text, font.ptr); + sf.c.sfText_setFont(text, font._ptr); sf.c.sfText_setCharacterSize(text, @intCast(c_uint, character_size)); sf.c.sfText_setString(text, string); - return Text{ .ptr = text.? }; + return Text{ ._ptr = text.? }; } /// Destroys a text -pub fn destroy(self: Text) void { - sf.c.sfText_destroy(self.ptr); +pub fn destroy(self: *Text) void { + sf.c.sfText_destroy(self._ptr); } // Draw function -pub fn sfDraw(self: Text, window: sf.RenderWindow, states: ?*sf.c.sfRenderStates) void { - sf.c.sfRenderWindow_drawText(window.ptr, self.ptr, states); +pub fn sfDraw(self: Text, window: anytype, states: ?*sf.c.sfRenderStates) void { + switch (@TypeOf(window)) { + sf.RenderWindow => sf.c.sfRenderWindow_drawText(window._ptr, self._ptr, states), + sf.RenderTexture => sf.c.sfRenderTexture_drawText(window._ptr, self._ptr, states), + else => @compileError("window must be a render target"), + } } // Getters/setters /// Sets the content of this text -pub fn setString(self: Text, string: [:0]const u8) void { - sf.c.sfText_setString(self.ptr, string); +pub fn setString(self: *Text, string: [:0]const u8) void { + sf.c.sfText_setString(self._ptr, string); } /// Sets the font of this text -pub fn setFont(self: Text, font: sf.Font) void { - sf.c.sfText_setFont(self.ptr, font.ptr); +pub fn setFont(self: *Text, font: sf.Font) void { + sf.c.sfText_setFont(self._ptr, font._ptr); } /// Gets the character size of this text pub fn getCharacterSize(self: Text) usize { - return @intCast(usize, sf.c.sfText_getCharacterSize(self.ptr)); + return @intCast(usize, sf.c.sfText_getCharacterSize(self._ptr)); } /// Sets the character size of this text -pub fn setCharacterSize(self: Text, character_size: usize) void { - sf.c.sfText_setCharacterSize(self.ptr, @intCast(c_uint, character_size)); +pub fn setCharacterSize(self: *Text, character_size: usize) void { + sf.c.sfText_setCharacterSize(self._ptr, @intCast(c_uint, character_size)); } /// Gets the fill color of this text pub fn getFillColor(self: Text) sf.Color { - return sf.Color.fromCSFML(sf.c.sfText_getFillColor(self.ptr)); + return sf.Color._fromCSFML(sf.c.sfText_getFillColor(self._ptr)); } /// Sets the fill color of this text -pub fn setFillColor(self: Text, color: sf.Color) void { - sf.c.sfText_setFillColor(self.ptr, color.toCSFML()); +pub fn setFillColor(self: *Text, color: sf.Color) void { + sf.c.sfText_setFillColor(self._ptr, color._toCSFML()); } /// Gets the outline color of this text pub fn getOutlineColor(self: Text) sf.Color { - return sf.Color.fromCSFML(sf.c.sfText_getOutlineColor(self.ptr)); + return sf.Color._fromCSFML(sf.c.sfText_getOutlineColor(self._ptr)); } /// Sets the outline color of this text -pub fn setOutlineColor(self: Text, color: sf.Color) void { - sf.c.sfText_setOutlineColor(self.ptr, color.toCSFML()); +pub fn setOutlineColor(self: *Text, color: sf.Color) void { + sf.c.sfText_setOutlineColor(self._ptr, color._toCSFML()); } /// Gets the outline thickness of this text pub fn getOutlineThickness(self: Text) f32 { - return sf.c.sfText_getOutlineThickness(self.ptr); + return sf.c.sfText_getOutlineThickness(self._ptr); } /// Sets the outline thickness of this text -pub fn setOutlineThickness(self: Text, thickness: f32) void { - sf.c.sfText_setOutlineThickness(self.ptr, thickness); +pub fn setOutlineThickness(self: *Text, thickness: f32) void { + sf.c.sfText_setOutlineThickness(self._ptr, thickness); } /// Gets the position of this text pub fn getPosition(self: Text) sf.Vector2f { - return sf.Vector2f.fromCSFML(sf.c.sfText_getPosition(self.ptr)); + return sf.Vector2f._fromCSFML(sf.c.sfText_getPosition(self._ptr)); } /// Sets the position of this text -pub fn setPosition(self: Text, pos: sf.Vector2f) void { - sf.c.sfText_setPosition(self.ptr, pos.toCSFML()); +pub fn setPosition(self: *Text, pos: sf.Vector2f) void { + sf.c.sfText_setPosition(self._ptr, pos._toCSFML()); } /// Adds the offset to this text -pub fn move(self: Text, offset: sf.Vector2f) void { - sf.c.sfText_move(self.ptr, offset.toCSFML()); +pub fn move(self: *Text, offset: sf.Vector2f) void { + sf.c.sfText_move(self._ptr, offset._toCSFML()); } /// Gets the origin of this text pub fn getOrigin(self: Text) sf.Vector2f { - return sf.Vector2f.fromCSFML(sf.c.sfText_getOrigin(self.ptr)); + return sf.Vector2f._fromCSFML(sf.c.sfText_getOrigin(self._ptr)); } /// Sets the origin of this text -pub fn setOrigin(self: Text, origin: sf.Vector2f) void { - sf.c.sfText_setOrigin(self.ptr, origin.toCSFML()); +pub fn setOrigin(self: *Text, origin: sf.Vector2f) void { + sf.c.sfText_setOrigin(self._ptr, origin._toCSFML()); } /// Gets the rotation of this text pub fn getRotation(self: Text) f32 { - return sf.c.sfText_getRotation(self.ptr); + return sf.c.sfText_getRotation(self._ptr); } /// Sets the rotation of this text -pub fn setRotation(self: Text, angle: f32) void { - sf.c.sfText_setRotation(self.ptr, angle); +pub fn setRotation(self: *Text, angle: f32) void { + sf.c.sfText_setRotation(self._ptr, angle); } /// Rotates this text by a given amount -pub fn rotate(self: Text, angle: f32) void { - sf.c.sfText_rotate(self.ptr, angle); +pub fn rotate(self: *Text, angle: f32) void { + sf.c.sfText_rotate(self._ptr, angle); } /// Gets the scale of this text pub fn getScale(self: Text) sf.Vector2f { - return sf.Vector2f.fromCSFML(sf.c.sfText_getScale(self.ptr)); + return sf.Vector2f._fromCSFML(sf.c.sfText_getScale(self._ptr)); } /// Sets the scale of this text -pub fn setScale(self: Text, factor: sf.Vector2f) void { - sf.c.sfText_setScale(self.ptr, factor.toCSFML()); +pub fn setScale(self: *Text, factor: sf.Vector2f) void { + sf.c.sfText_setScale(self._ptr, factor._toCSFML()); } /// Scales this text -pub fn scale(self: Text, factor: sf.Vector2f) void { - sf.c.sfText_scale(self.ptr, factor.toCSFML()); +pub fn scale(self: *Text, factor: sf.Vector2f) void { + sf.c.sfText_scale(self._ptr, factor._toCSFML()); } /// return the position of the index-th character pub fn findCharacterPos(self: Text, index: usize) sf.Vector2f { - return sf.Vector2f.fromCSFML(sf.c.sfText_findCharacterPos(self.ptr, index)); + return sf.Vector2f._fromCSFML(sf.c.sfText_findCharacterPos(self._ptr, index)); } /// Gets the letter spacing factor pub fn getLetterSpacing(self: Text) f32 { - return sf.c.sfText_getLetterSpacing(self.ptr); + return sf.c.sfText_getLetterSpacing(self._ptr); } /// Sets the letter spacing factor -pub fn setLetterSpacing(self: Text, spacing_factor: f32) void { - sf.c.sfText_setLetterSpacing(self.ptr, spacing_factor); +pub fn setLetterSpacing(self: *Text, spacing_factor: f32) void { + sf.c.sfText_setLetterSpacing(self._ptr, spacing_factor); } /// Gets the line spacing factor pub fn getLineSpacing(self: Text) f32 { - return sf.c.sfText_getLineSpacing(self.ptr); + return sf.c.sfText_getLineSpacing(self._ptr); } /// Sets the line spacing factor -pub fn setLineSpacing(self: Text, spacing_factor: f32) void { - sf.c.sfText_setLineSpacing(self.ptr, spacing_factor); +pub fn setLineSpacing(self: *Text, spacing_factor: f32) void { + sf.c.sfText_setLineSpacing(self._ptr, spacing_factor); } /// Gets the local bounding rectangle of the text pub fn getLocalBounds(self: Text) sf.FloatRect { - return sf.FloatRect.fromCSFML(sf.c.sfText_getLocalBounds(self.ptr)); + return sf.FloatRect._fromCSFML(sf.c.sfText_getLocalBounds(self._ptr)); } /// Gets the global bounding rectangle of the text pub fn getGlobalBounds(self: Text) sf.FloatRect { - return sf.FloatRect.fromCSFML(sf.c.sfText_getGlobalBounds(self.ptr)); + return sf.FloatRect._fromCSFML(sf.c.sfText_getGlobalBounds(self._ptr)); } pub const getTransform = @compileError("Function is not implemented yet."); pub const getInverseTransform = @compileError("Function is not implemented yet."); /// Pointer to the csfml font -ptr: *sf.c.sfText, +_ptr: *sf.c.sfText, test "text: sane getters and setters" { const tst = @import("std").testing; diff --git a/src/sfml/graphics/VertexArray.zig b/src/sfml/graphics/VertexArray.zig index ea4ccb2..d340600 100644 --- a/src/sfml/graphics/VertexArray.zig +++ b/src/sfml/graphics/VertexArray.zig @@ -14,19 +14,23 @@ pub fn createFromSlice(vertex: []const sf.graphics.Vertex, primitive: sf.graphic sf.c.sfVertexArray_resize(vert, vertex.len); for (vertex) |v, i| sf.c.sfVertexArray_getVertex(vert, i).* = @bitCast(sf.c.sfVertex, v); - return VertexArray{ .ptr = vert }; + return VertexArray{ ._ptr = vert }; } else return sf.Error.nullptrUnknownReason; } /// Destroys a vertex array -pub fn destroy(self: VertexArray) void { - sf.c.sfVertexArray_destroy(self.ptr); +pub fn destroy(self: *VertexArray) void { + sf.c.sfVertexArray_destroy(self._ptr); } // Draw function -pub fn sfDraw(self: VertexArray, window: sf.graphics.RenderWindow, states: ?*sf.c.sfRenderStates) void { - sf.c.sfRenderWindow_drawVertexArray(window.ptr, self.ptr, states); +pub fn sfDraw(self: VertexArray, window: anytype, states: ?*sf.c.sfRenderStates) void { + switch (@TypeOf(window)) { + sf.graphics.RenderWindow => sf.c.sfRenderWindow_drawVertexArray(window._ptr, self._ptr, states), + sf.graphics.RenderTexture => sf.c.sfRenderTexture_drawVertexArray(window._ptr, self._ptr, states), + else => @compileError("window must be a render target"), + } } /// Pointer to the csfml structure -ptr: *sf.c.sfVertexArray, +_ptr: *sf.c.sfVertexArray, diff --git a/src/sfml/graphics/View.zig b/src/sfml/graphics/View.zig index 6ce9610..130bb66 100644 --- a/src/sfml/graphics/View.zig +++ b/src/sfml/graphics/View.zig @@ -20,22 +20,22 @@ pub fn fromRect(rect: sf.FloatRect) View { /// Creates a view from a CSFML object /// This is mainly for the inner workings of this wrapper -pub fn fromCSFML(view: *const sf.c.sfView) View { +pub fn _fromCSFML(view: *const sf.c.sfView) View { var ret: View = undefined; - ret.center = sf.Vector2f.fromCSFML(sf.c.sfView_getCenter(view)); - ret.size = sf.Vector2f.fromCSFML(sf.c.sfView_getSize(view)); - ret.viewport = sf.FloatRect.fromCSFML(sf.c.sfView_getViewport(view)); + ret.center = sf.Vector2f._fromCSFML(sf.c.sfView_getCenter(view)); + ret.size = sf.Vector2f._fromCSFML(sf.c.sfView_getSize(view)); + ret.viewport = sf.FloatRect._fromCSFML(sf.c.sfView_getViewport(view)); return ret; } /// Creates a CSFML view from this view /// This is mainly for the inner workings of this wrapper /// The resulting view must be destroyed! -pub fn toCSFML(self: View) *sf.c.sfView { +pub fn _toCSFML(self: View) *sf.c.sfView { var view = sf.c.sfView_create().?; - sf.c.sfView_setCenter(view, self.center.toCSFML()); - sf.c.sfView_setSize(view, self.size.toCSFML()); - sf.c.sfView_setViewport(view, self.viewport.toCSFML()); + sf.c.sfView_setCenter(view, self.center._toCSFML()); + sf.c.sfView_setSize(view, self.size._toCSFML()); + sf.c.sfView_setViewport(view, self.viewport._toCSFML()); return view; } @@ -74,13 +74,13 @@ test "view: from rect" { // Testing if the view from rect initialization works var rect = sf.FloatRect.init(10, -15, 700, 600); - var view = sf.c.sfView_createFromRect(rect.toCSFML()); + var view = sf.c.sfView_createFromRect(rect._toCSFML()); defer sf.c.sfView_destroy(view); var view2 = View.fromRect(rect); - var center = sf.Vector2f.fromCSFML(sf.c.sfView_getCenter(view)); - var size = sf.Vector2f.fromCSFML(sf.c.sfView_getSize(view)); + var center = sf.Vector2f._fromCSFML(sf.c.sfView_getCenter(view)); + var size = sf.Vector2f._fromCSFML(sf.c.sfView_getSize(view)); try tst.expectApproxEqAbs(center.x, view2.center.x, 0.00001); try tst.expectApproxEqAbs(center.y, view2.center.y, 0.00001); diff --git a/src/sfml/graphics/color.zig b/src/sfml/graphics/color.zig index 5555c22..bea5666 100644 --- a/src/sfml/graphics/color.zig +++ b/src/sfml/graphics/color.zig @@ -6,13 +6,13 @@ const math = @import("std").math; pub const Color = packed struct { /// Converts a color from a csfml object /// For inner workings - pub fn fromCSFML(col: sf.c.sfColor) Color { + pub fn _fromCSFML(col: sf.c.sfColor) Color { return @bitCast(Color, col); } /// Converts this color to a csfml one /// For inner workings - pub fn toCSFML(self: Color) sf.c.sfColor { + pub fn _toCSFML(self: Color) sf.c.sfColor { return @bitCast(sf.c.sfColor, self); } @@ -55,7 +55,7 @@ pub const Color = packed struct { } /// Creates a color with rgba floats from 0 to 1 - pub fn fromFloats(red: f32, green: f32, blue: f32, alpha: f32) Color { + fn fromFloats(red: f32, green: f32, blue: f32, alpha: f32) Color { return Color{ .r = @floatToInt(u8, math.clamp(red, 0.0, 1.0) * 255.0), .g = @floatToInt(u8, math.clamp(green, 0.0, 1.0) * 255.0), @@ -97,6 +97,25 @@ pub const Color = packed struct { }; } + /// Get a GLSL float vector for this color (for shaders) + pub fn toFVec4(self: Color) sf.graphics.glsl.FVec4 { + return .{ + .x = @intToFloat(f32, self.r) / 255.0, + .y = @intToFloat(f32, self.g) / 255.0, + .z = @intToFloat(f32, self.b) / 255.0, + .w = @intToFloat(f32, self.a) / 255.0 + }; + } + /// Get a GLSL int vector for this color (for shaders) + pub fn toIVec4(self: Color) sf.graphcis.glsl.IVec4 { + return .{ + .x = self.r, + .y = self.g, + .z = self.b, + .w = self.a + }; + } + // Colors /// Black color pub const Black = Color.fromRGB(0, 0, 0); @@ -138,7 +157,7 @@ test "color: conversions" { var csfml_col = sf.c.sfColor_fromInteger(@as(c_uint, code)); - try tst.expectEqual(Color.fromCSFML(csfml_col), col); + try tst.expectEqual(Color._fromCSFML(csfml_col), col); } test "color: hsv to rgb" { @@ -153,14 +172,14 @@ test "color: sane from/to CSFML color" { const tst = @import("std").testing; const col = Color.fromRGBA(5, 12, 28, 127); - const ccol = col.toCSFML(); + const ccol = col._toCSFML(); try tst.expectEqual(col.r, ccol.r); try tst.expectEqual(col.g, ccol.g); try tst.expectEqual(col.b, ccol.b); try tst.expectEqual(col.a, ccol.a); - const col2 = Color.fromCSFML(ccol); + const col2 = Color._fromCSFML(ccol); try tst.expectEqual(col, col2); } diff --git a/src/sfml/graphics/glsl.zig b/src/sfml/graphics/glsl.zig new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/src/sfml/graphics/glsl.zig @@ -0,0 +1,16 @@ +const sf = @import("../sfml.zig").system; + +pub const FVec2 = sf.Vector2(f32); +pub const FVec3 = sf.Vector3(f32); +pub const FVec4 = sf.Vector4(f32); + +pub const IVec2 = sf.Vector2(c_int); +pub const IVec3 = sf.Vector3(c_int); +pub const IVec4 = sf.Vector4(c_int); + +pub const BVec2 = sf.Vector2(bool); +pub const BVec3 = sf.Vector3(bool); +pub const BVec4 = sf.Vector4(bool); + +pub const Mat3 = [3 * 3]f32; +pub const Mat4 = [4 * 4]f32;
\ No newline at end of file diff --git a/src/sfml/graphics/rect.zig b/src/sfml/graphics/rect.zig index ace7397..2d7d0ef 100644 --- a/src/sfml/graphics/rect.zig +++ b/src/sfml/graphics/rect.zig @@ -29,14 +29,14 @@ pub fn Rect(comptime T: type) type { /// Makes a CSFML rect with this rect (only if the corresponding type exists) /// This is mainly for the inner workings of this wrapper - pub fn toCSFML(self: Self) CsfmlEquivalent { + pub fn _toCSFML(self: Self) CsfmlEquivalent { if (CsfmlEquivalent == void) @compileError("This rectangle type doesn't have a CSFML equivalent."); return @bitCast(CsfmlEquivalent, self); } /// Creates a rect from a CSFML one (only if the corresponding type exists) /// This is mainly for the inner workings of this wrapper - pub fn fromCSFML(rect: CsfmlEquivalent) Self { + pub fn _fromCSFML(rect: CsfmlEquivalent) Self { if (CsfmlEquivalent == void) @compileError("This rectangle type doesn't have a CSFML equivalent."); return @bitCast(Self, rect); } @@ -124,11 +124,11 @@ test "rect: intersect" { var inter1: sf.c.sfIntRect = undefined; var inter2: sf.c.sfIntRect = undefined; - try tst.expectEqual(sf.c.sfIntRect_intersects(&r1.toCSFML(), &r2.toCSFML(), &inter1), 1); - try tst.expectEqual(sf.c.sfIntRect_intersects(&r1.toCSFML(), &r3.toCSFML(), &inter2), 1); + try tst.expectEqual(sf.c.sfIntRect_intersects(&r1._toCSFML(), &r2._toCSFML(), &inter1), 1); + try tst.expectEqual(sf.c.sfIntRect_intersects(&r1._toCSFML(), &r3._toCSFML(), &inter2), 1); - try tst.expectEqual(Rect(c_int).fromCSFML(inter1), r1.intersects(r2).?); - try tst.expectEqual(Rect(c_int).fromCSFML(inter2), r1.intersects(r3).?); + try tst.expectEqual(Rect(c_int)._fromCSFML(inter1), r1.intersects(r2).?); + try tst.expectEqual(Rect(c_int)._fromCSFML(inter2), r1.intersects(r3).?); } test "rect: contains" { @@ -147,14 +147,14 @@ test "rect: sane from/to CSFML rect" { inline for ([_]type{ c_int, f32 }) |T| { const rect = Rect(T).init(1, 3, 5, 10); - const crect = rect.toCSFML(); + const crect = rect._toCSFML(); try tst.expectEqual(rect.left, crect.left); try tst.expectEqual(rect.top, crect.top); try tst.expectEqual(rect.width, crect.width); try tst.expectEqual(rect.height, crect.height); - const rect2 = Rect(T).fromCSFML(crect); + const rect2 = Rect(T)._fromCSFML(crect); try tst.expectEqual(rect, rect2); } diff --git a/src/sfml/graphics/texture.zig b/src/sfml/graphics/texture.zig index 317738a..55de1ae 100644 --- a/src/sfml/graphics/texture.zig +++ b/src/sfml/graphics/texture.zig @@ -9,84 +9,89 @@ const sf = struct { const std = @import("std"); const assert = std.debug.assert; -const TextureType = enum { ptr, const_ptr }; +const TextureType = enum { _ptr, _const_ptr }; pub const Texture = union(TextureType) { - const Self = @This(); - // Constructor/destructor /// Creates a texture from nothing - pub fn create(size: sf.Vector2u) !Self { - var tex = sf.c.sfTexture_create(@intCast(c_uint, size.x), @intCast(c_uint, size.y)); + pub fn create(size: sf.Vector2u) !Texture { + const tex = sf.c.sfTexture_create(@intCast(c_uint, size.x), @intCast(c_uint, size.y)); if (tex == null) return sf.Error.nullptrUnknownReason; - return Self{ .ptr = tex.? }; + return Texture{ ._ptr = tex.? }; } /// Loads a texture from a file - pub fn createFromFile(path: [:0]const u8) !Self { - var tex = sf.c.sfTexture_createFromFile(path, null); + pub fn createFromFile(path: [:0]const u8) !Texture { + const tex = sf.c.sfTexture_createFromFile(path, null); if (tex == null) return sf.Error.resourceLoadingError; - return Self{ .ptr = tex.? }; + return Texture{ ._ptr = tex.? }; } /// Creates an texture from an image - pub fn createFromImage(image: sf.Image, area: ?sf.IntRect) !Self { - var tex = if (area) |a| - sf.c.sfTexture_createFromImage(image.ptr, &a.toCSFML()) + pub fn createFromImage(image: sf.Image, area: ?sf.IntRect) !Texture { + const tex = if (area) |a| + sf.c.sfTexture_createFromImage(image._ptr, &a._toCSFML()) else - sf.c.sfTexture_createFromImage(image.ptr, null); + sf.c.sfTexture_createFromImage(image._ptr, null); if (tex == null) return sf.Error.nullptrUnknownReason; - return Self{ .ptr = tex.? }; + return Texture{ ._ptr = tex.? }; } /// Destroys a texture /// Be careful, you can only destroy non const textures - pub fn destroy(self: Self) void { + pub fn destroy(self: *Texture) void { // TODO : is it possible to detect that comptime? // Should this panic? - if (self == .const_ptr) + if (self.* == ._const_ptr) @panic("Can't destroy a const texture pointer"); - sf.c.sfTexture_destroy(self.ptr); + sf.c.sfTexture_destroy(self._ptr); } // Getters/Setters /// Gets a const pointer to this texture - pub fn get(self: Self) *const sf.c.sfTexture { + /// For inner workings + pub fn _get(self: Texture) *const sf.c.sfTexture { return switch (self) { - .ptr => self.ptr, - .const_ptr => self.const_ptr, + ._ptr => self._ptr, + ._const_ptr => self._const_ptr, }; } + /// Clones this texture (the clone won't be const) - pub fn copy(self: Self) !Self { - var cpy = sf.c.sfTexture_copy(self.get()); + pub fn copy(self: Texture) !Texture { + const cpy = sf.c.sfTexture_copy(self._get()); if (cpy == null) return sf.Error.nullptrUnknownReason; - return Self{ .ptr = cpy.? }; + return Texture{ ._ptr = cpy.? }; } + /// Copy this texture to an image in ram + pub fn copyToImage(self: Texture) sf.Image { + return .{ ._ptr = sf.c.sfTexture_copyToImage(self._get()).? }; + } + /// Makes this texture constant (I don't know why you would do that) - pub fn makeConst(self: *Self) void { - self.* = Self{ .const_ptr = self.get() }; + pub fn makeConst(self: *Texture) void { + self.* = Texture{ ._const_ptr = self._get() }; } /// Gets the size of this image - pub fn getSize(self: Self) sf.Vector2u { - const size = sf.c.sfTexture_getSize(self.get()); + pub fn getSize(self: Texture) sf.Vector2u { + const size = sf.c.sfTexture_getSize(self._get()); return sf.Vector2u{ .x = size.x, .y = size.y }; } /// Gets the pixel count of this image - pub fn getPixelCount(self: Self) usize { - var dim = self.getSize(); + pub fn getPixelCount(self: Texture) usize { + const dim = self.getSize(); return dim.x * dim.y; } /// Updates the pixels of the image from an array of pixels (colors) - pub fn updateFromPixels(self: Self, pixels: []const sf.Color, zone: ?sf.Rect(c_uint)) !void { - if (self == .const_ptr) + pub fn updateFromPixels(self: *Texture, pixels: []const sf.Color, zone: ?sf.Rect(c_uint)) !void { + if (self.* == ._const_ptr) @panic("Can't set pixels on a const texture"); if (self.isSrgb()) @panic("Updating an srgb from a pixel array isn't implemented"); @@ -114,78 +119,94 @@ pub const Texture = union(TextureType) { if (pixels.len < real_zone.width * real_zone.height) return sf.Error.notEnoughData; - sf.c.sfTexture_updateFromPixels(self.ptr, @ptrCast([*]const u8, pixels.ptr), real_zone.width, real_zone.height, real_zone.left, real_zone.top); + sf.c.sfTexture_updateFromPixels(self._ptr, @ptrCast([*]const u8, pixels.ptr), real_zone.width, real_zone.height, real_zone.left, real_zone.top); } /// Updates the pixels of the image from an other texture - pub fn updateFromTexture(self: Self, other: Texture, copy_pos: ?sf.Vector2u) void { + pub fn updateFromTexture(self: *Texture, other: Texture, copy_pos: ?sf.Vector2u) void { + if (self == ._const_ptr) + @panic("Can't set pixels on a const texture"); + var pos = if (copy_pos) |a| a else sf.Vector2u{ .x = 0, .y = 0 }; var max = other.getSize().add(pos); var size = self.getSize(); - assert(max.x < size.x and max.y < size.y); + assert(max.x <= size.x and max.y <= size.y); - sf.c.sfTexture_updateFromTexture(self.ptr, other.get(), pos.x, pos.y); + sf.c.sfTexture_updateFromTexture(self._ptr, other._get(), pos.x, pos.y); } /// Updates the pixels of the image from an image - pub fn updateFromImage(self: Self, image: sf.Image, copy_pos: ?sf.Vector2u) void { + pub fn updateFromImage(self: *Texture, image: sf.Image, copy_pos: ?sf.Vector2u) void { + if (self.* == ._const_ptr) + @panic("Can't set pixels on a const texture"); + var pos = if (copy_pos) |a| a else sf.Vector2u{ .x = 0, .y = 0 }; var max = image.getSize().add(pos); var size = self.getSize(); - assert(max.x < size.x and max.y < size.y); + assert(max.x <= size.x and max.y <= size.y); - sf.c.sfTexture_updateFromImage(self.ptr, image.ptr, pos.x, pos.y); + sf.c.sfTexture_updateFromImage(self._ptr, image._ptr, pos.x, pos.y); } /// Tells whether or not this texture is to be smoothed - pub fn isSmooth(self: Self) bool { - return sf.c.sfTexture_isSmooth(self.ptr) != 0; + pub fn isSmooth(self: Texture) bool { + return sf.c.sfTexture_isSmooth(self._ptr) != 0; } /// Enables or disables texture smoothing - pub fn setSmooth(self: Self, smooth: bool) void { - if (self == .const_ptr) + pub fn setSmooth(self: *Texture, smooth: bool) void { + if (self.* == ._const_ptr) @panic("Can't set properties on a const texture"); - sf.c.sfTexture_setSmooth(self.ptr, if (smooth) 1 else 0); + sf.c.sfTexture_setSmooth(self._ptr, @boolToInt(smooth)); } /// Tells whether or not this texture should repeat when rendering outside its bounds - pub fn isRepeated(self: Self) bool { - return sf.c.sfTexture_isRepeated(self.ptr) != 0; + pub fn isRepeated(self: Texture) bool { + return sf.c.sfTexture_isRepeated(self._ptr) != 0; } /// Enables or disables texture repeating - pub fn setRepeated(self: Self, repeated: bool) void { - if (self == .const_ptr) + pub fn setRepeated(self: *Texture, repeated: bool) void { + if (self.* == ._const_ptr) @panic("Can't set properties on a const texture"); - sf.c.sfTexture_setRepeated(self.ptr, if (repeated) 1 else 0); + sf.c.sfTexture_setRepeated(self._ptr, @boolToInt(repeated)); } /// Tells whether or not this texture has colors in the SRGB format /// SRGB functions arent implemented yet - pub fn isSrgb(self: Self) bool { - return sf.c.sfTexture_isSrgb(self.ptr) != 0; + pub fn isSrgb(self: Texture) bool { + return sf.c.sfTexture_isSrgb(self._ptr) != 0; } /// Enables or disables SRGB - pub fn setSrgb(self: Self, srgb: bool) void { - if (self == .const_ptr) + pub fn setSrgb(self: *Texture, srgb: bool) void { + if (self.* == ._const_ptr) @panic("Can't set properties on a const texture"); - sf.c.sfTexture_setSrgb(self.ptr, if (srgb) 1 else 0); + sf.c.sfTexture_setSrgb(self._ptr, @boolToInt(srgb)); } /// Swaps this texture's contents with an other texture - pub fn swap(self: Self, other: Texture) void { - if (self == .const_ptr or other == .const_ptr) + pub fn swap(self: *Texture, other: *Texture) void { + if (self.* == ._const_ptr or other.* == ._const_ptr) @panic("Texture swapping must be done between two non const textures"); - sf.c.sfTexture_swap(self.ptr, other.ptr); + sf.c.sfTexture_swap(self._ptr, other._ptr); + } + + // Others + + /// Generates a mipmap for the current texture data, returns true if the operation succeeded + pub fn generateMipmap(self: *Texture) bool { + if (self == ._const_ptr) + @panic("Can't act on a const texture"); + + return sf.c.sfTexture_generateMipmap(self._ptr) != 0; } /// Pointer to the csfml texture - ptr: *sf.c.sfTexture, + _ptr: *sf.c.sfTexture, /// Const pointer to the csfml texture - const_ptr: *const sf.c.sfTexture + _const_ptr: *const sf.c.sfTexture }; test "texture: sane getters and setters" { @@ -212,12 +233,21 @@ test "texture: sane getters and setters" { c.* = sf.graphics.Color.fromHSVA(@intToFloat(f32, i) / 144 * 360, 100, 100, 1); } + pixel_data[0] = sf.Color.Green; + try tex.updateFromPixels(pixel_data, null); try tst.expect(!tex.isSrgb()); try tst.expect(tex.isSmooth()); try tst.expect(tex.isRepeated()); + var img = tex.copyToImage(); + defer img.destroy(); + + try tst.expectEqual(sf.Color.Green, img.getPixel(.{ .x = 0, .y = 0 })); + + tex.updateFromImage(img, null); + var t = tex; t.makeConst(); @@ -228,7 +258,7 @@ test "texture: sane getters and setters" { var tex2 = try Texture.create(.{ .x = 100, .y = 100 }); defer tex2.destroy(); - copy.swap(tex2); + copy.swap(&tex2); try tst.expectEqual(@as(usize, 100 * 100), copy.getPixelCount()); try tst.expectEqual(@as(usize, 120), tex2.getPixelCount()); diff --git a/src/sfml/sfml.zig b/src/sfml/sfml.zig index da1dc4b..2cf51f2 100644 --- a/src/sfml/sfml.zig +++ b/src/sfml/sfml.zig @@ -5,11 +5,15 @@ pub const c = @import("sfml_import.zig").c; pub const Error = @import("sfml_errors.zig").Error; pub const system = struct { - pub const Vector2 = @import("system/vector.zig").Vector2; + const vector = @import("system/vector.zig"); + pub const Vector2 = vector.Vector2; + pub const Vector3 = vector.Vector3; + pub const Vector4 = vector.Vector4; pub const Vector2i = Vector2(c_int); pub const Vector2u = Vector2(c_uint); pub const Vector2f = Vector2(f32); - pub const Vector3f = @import("system/vector.zig").Vector3f; + pub const Vector3f = Vector3(f32); + pub const Time = @import("system/Time.zig"); pub const Clock = @import("system/Clock.zig"); }; @@ -17,27 +21,42 @@ pub const system = struct { pub const window = struct { pub const Event = @import("window/event.zig").Event; pub const Style = @import("window/Style.zig"); + pub const WindowHandle = c.sfWindowHandle; + pub const ContextSettings = @import("window/context_settings.zig").ContextSettings; pub const keyboard = @import("window/keyboard.zig"); pub const mouse = @import("window/mouse.zig"); }; pub const graphics = struct { pub const Color = @import("graphics/color.zig").Color; + pub const RenderWindow = @import("graphics/RenderWindow.zig"); + pub const RenderTexture = @import("graphics/RenderTexture.zig"); + + pub const View = @import("graphics/View.zig"); + pub const Image = @import("graphics/Image.zig"); pub const Texture = @import("graphics/texture.zig").Texture; + pub const Sprite = @import("graphics/Sprite.zig"); pub const CircleShape = @import("graphics/CircleShape.zig"); pub const RectangleShape = @import("graphics/RectangleShape.zig"); + + pub const Vertex = @import("graphics/vertex.zig").Vertex; + pub const VertexArray = @import("graphics/VertexArray.zig"); + pub const PrimitiveType = @import("graphics/primitive_type.zig").PrimitiveType; + pub const Rect = @import("graphics/rect.zig").Rect; pub const IntRect = Rect(c_int); pub const FloatRect = Rect(f32); - pub const View = @import("graphics/View.zig"); + pub const Font = @import("graphics/Font.zig"); pub const Text = @import("graphics/Text.zig"); - pub const Vertex = @import("graphics/vertex.zig").Vertex; - pub const VertexArray = @import("graphics/VertexArray.zig"); - pub const PrimitiveType = @import("graphics/primitive_type.zig").PrimitiveType; + + pub const glsl = @import("graphics/glsl.zig"); + pub const Shader = @import("graphics/Shader.zig"); + pub const BlendMode = @import("graphics/BlendMode.zig"); + pub const RenderStates = @import("graphics/RenderStates.zig"); }; pub const audio = struct { @@ -48,15 +67,11 @@ pub const audio = struct { pub const network = @compileError("network module: to be implemented one day"); +pub const VertexBuffer = @compileError("VertexArray not available yet"); +pub const Transform = @compileError("Transform not available yet"); + pub const touch = @compileError("touch not available yet"); pub const joystick = @compileError("Joystick not available yet"); pub const sensor = @compileError("Sensor not available yet"); pub const clipboard = @compileError("Clipboard not available yet"); pub const Cursor = @compileError("Cursor not available yet"); - -pub const VertexBuffer = @compileError("VertexArray not available yet"); -pub const BlendMode = @compileError("BlendMode not available yet"); -pub const RenderStates = @compileError("RenderStates not available yet"); -pub const RenderTexture = @compileError("RenderTexture not available yet"); -pub const Shader = @compileError("Shader not available yet"); -pub const Transform = @compileError("Transform not available yet"); diff --git a/src/sfml/system/Clock.zig b/src/sfml/system/Clock.zig index d8b174e..74b73ab 100644 --- a/src/sfml/system/Clock.zig +++ b/src/sfml/system/Clock.zig @@ -17,29 +17,29 @@ pub fn create() !Clock { if (clock == null) return sf.Error.nullptrUnknownReason; - return Clock{ .ptr = clock.? }; + return Clock{ ._ptr = clock.? }; } /// Destroys this clock -pub fn destroy(self: Clock) void { - sf.c.sfClock_destroy(self.ptr); +pub fn destroy(self: *Clock) void { + sf.c.sfClock_destroy(self._ptr); } // Clock control /// Gets the elapsed seconds pub fn getElapsedTime(self: Clock) sf.Time { - var time = sf.c.sfClock_getElapsedTime(self.ptr).microseconds; + var time = sf.c.sfClock_getElapsedTime(self._ptr).microseconds; return sf.Time{ .us = time }; } /// Gets the elapsed seconds and restarts the timer -pub fn restart(self: Clock) sf.Time { - var time = sf.c.sfClock_restart(self.ptr).microseconds; +pub fn restart(self: *Clock) sf.Time { + var time = sf.c.sfClock_restart(self._ptr).microseconds; return sf.Time{ .us = time }; } /// Pointer to the csfml structure -ptr: *sf.c.sfClock, +_ptr: *sf.c.sfClock, test "clock: sleep test" { const tst = @import("std").testing; diff --git a/src/sfml/system/Time.zig b/src/sfml/system/Time.zig index 2e8a34c..ae5152a 100644 --- a/src/sfml/system/Time.zig +++ b/src/sfml/system/Time.zig @@ -8,13 +8,13 @@ const Time = @This(); /// Converts a time from a csfml object /// For inner workings -pub fn fromCSFML(time: sf.c.sfTime) Time { +pub fn _fromCSFML(time: sf.c.sfTime) Time { return Time{ .us = time.microseconds }; } /// Converts a time to a csfml object /// For inner workings -pub fn toCSFML(self: Time) sf.c.sfTime { +pub fn _toCSFML(self: Time) sf.c.sfTime { return sf.c.sfTime{ .microseconds = self.us }; } @@ -54,7 +54,7 @@ pub fn asSeconds(self: Time) f32 { /// Sleeps the amount of time specified pub fn sleep(time: Time) void { - sf.c.sfSleep(time.toCSFML()); + sf.c.sfSleep(time._toCSFML()); } /// A time of zero @@ -75,19 +75,19 @@ pub const TimeSpan = struct { /// Converts a timespan from a csfml object /// For inner workings - pub fn fromCSFML(span: sf.c.sfTimeSpan) TimeSpan { + pub fn _fromCSFML(span: sf.c.sfTimeSpan) TimeSpan { return TimeSpan{ - .offset = Time.fromCSFML(span.offset), - .length = Time.fromCSFML(span.length), + .offset = Time._fromCSFML(span.offset), + .length = Time._fromCSFML(span.length), }; } /// Converts a timespan to a csfml object /// For inner workings - pub fn toCSFML(self: TimeSpan) sf.c.sfTimeSpan { + pub fn _toCSFML(self: TimeSpan) sf.c.sfTimeSpan { return sf.c.sfTimeSpan{ - .offset = self.offset.toCSFML(), - .length = self.length.toCSFML(), + .offset = self.offset._toCSFML(), + .length = self.length._toCSFML(), }; } diff --git a/src/sfml/system/vector.zig b/src/sfml/system/vector.zig index 7e3e500..3190d59 100644 --- a/src/sfml/system/vector.zig +++ b/src/sfml/system/vector.zig @@ -2,6 +2,7 @@ const sf = @import("../sfml_import.zig"); +/// Template for a 2 dimensional vector pub fn Vector2(comptime T: type) type { return packed struct { const Self = @This(); @@ -16,14 +17,14 @@ pub fn Vector2(comptime T: type) type { /// Makes a CSFML vector with this vector (only if the corresponding type exists) /// This is mainly for the inner workings of this wrapper - pub fn toCSFML(self: Self) CsfmlEquivalent { + pub fn _toCSFML(self: Self) CsfmlEquivalent { if (CsfmlEquivalent == void) @compileError("This vector type doesn't have a CSFML equivalent."); return @bitCast(CsfmlEquivalent, self); } /// Creates a vector from a CSFML one (only if the corresponding type exists) /// This is mainly for the inner workings of this wrapper - pub fn fromCSFML(vec: CsfmlEquivalent) Self { + pub fn _fromCSFML(vec: CsfmlEquivalent) Self { if (CsfmlEquivalent == void) @compileError("This vector type doesn't have a CSFML equivalent."); return @bitCast(Self, vec); } @@ -50,28 +51,64 @@ pub fn Vector2(comptime T: type) type { }; } -pub const Vector3f = struct { - const Self = @This(); +/// Template for a 3 dimensional vector +pub fn Vector3(comptime T: type) type { + return packed struct { + const Self = @This(); - /// Makes a CSFML vector with this vector (only if the corresponding type exists) - /// This is mainly for the inner workings of this wrapper - pub fn toCSFML(self: Self) sf.c.sfVector3f { - return @bitCast(sf.c.sfVector3f, self); - } + /// Makes a CSFML vector with this vector (only if the corresponding type exists) + /// This is mainly for the inner workings of this wrapper + pub fn _toCSFML(self: Self) sf.c.sfVector3f { + if (T != f32) @compileError("This vector type doesn't have a CSFML equivalent."); + return @bitCast(sf.c.sfVector3f, self); + } - /// Creates a vector from a CSFML one (only if the corresponding type exists) - /// This is mainly for the inner workings of this wrapper - pub fn fromCSFML(vec: sf.c.sfVector3f) Self { - return @bitCast(Self, vec); - } + /// Creates a vector from a CSFML one (only if the corresponding type exists) + /// This is mainly for the inner workings of this wrapper + pub fn _fromCSFML(vec: sf.c.sfVector3f) Self { + if (T != f32) @compileError("This vector type doesn't have a CSFML equivalent."); + return @bitCast(Self, vec); + } + + /// Adds two vectors + pub fn add(self: Self, other: Self) Self { + return Self{ .x = self.x + other.x, .y = self.y + other.y, .z = self.z + other.z }; + } + + /// Substracts two vectors + pub fn substract(self: Self, other: Self) Self { + return Self{ .x = self.x - other.x, .y = self.y - other.y, .z = self.z - other.z }; + } + + /// Scales a vector + pub fn scale(self: Self, scalar: T) Self { + return Self{ .x = self.x * scalar, .y = self.y * scalar, .z = self.z * scalar }; + } + + /// x component of the vector + x: T, + /// y component of the vector + y: T, + /// z component of the vector + z: T + }; +} - /// x component of the vector - x: f32, - /// y component of the vector - y: f32, - /// z component of the vector - z: f32, -}; +/// Template for a 4 dimensional vector +/// SFML doesn't really have this but as shaders use such vectors it can be here anyways +pub fn Vector4(comptime T: type) type { + return packed struct { + const Self = @This(); + /// x component of the vector + x: T, + /// y component of the vector + y: T, + /// z component of the vector + z: T, + /// w component of the vector + w: T + }; +} test "vector: sane from/to CSFML vectors" { const tst = @import("std").testing; @@ -79,25 +116,25 @@ test "vector: sane from/to CSFML vectors" { inline for ([_]type{ c_int, c_uint, f32 }) |T| { const VecT = Vector2(T); const vec = VecT{ .x = 1, .y = 3 }; - const cvec = vec.toCSFML(); + const cvec = vec._toCSFML(); try tst.expectEqual(vec.x, cvec.x); try tst.expectEqual(vec.y, cvec.y); - const vec2 = VecT.fromCSFML(cvec); + const vec2 = VecT._fromCSFML(cvec); try tst.expectEqual(vec, vec2); } { - const vec = Vector3f{ .x = 1, .y = 3.5, .z = -12 }; - const cvec = vec.toCSFML(); + const vec = Vector3(f32){ .x = 1, .y = 3.5, .z = -12 }; + const cvec = vec._toCSFML(); try tst.expectEqual(vec.x, cvec.x); try tst.expectEqual(vec.y, cvec.y); try tst.expectEqual(vec.z, cvec.z); - const vec2 = Vector3f.fromCSFML(cvec); + const vec2 = Vector3(f32)._fromCSFML(cvec); try tst.expectEqual(vec, vec2); } diff --git a/src/sfml/window/context_settings.zig b/src/sfml/window/context_settings.zig new file mode 100644 index 0000000..19b8f03 --- /dev/null +++ b/src/sfml/window/context_settings.zig @@ -0,0 +1,28 @@ +const sf = @import("../sfml.zig"); + +pub const ContextSettings = packed struct { + const PaddingType = @import("std").meta.Int(.unsigned, @bitSizeOf(c_int) - @bitSizeOf(bool)); + + depth_bits: c_uint = 0, + stencil_bits: c_uint = 0, + antialiasing_level: c_uint = 0, + major_version: c_uint = 1, + minor_version: c_uint = 1, + attribute_flags: u32 = 0, + srgb_capable: bool = false, + _padding: PaddingType = 0, + + pub const Attribute = struct { + pub const default: u32 = 0; + pub const core: u32 = 1; + pub const debug: u32 = 4; + }; + + pub fn _toCSFML(self: ContextSettings) sf.c.sfContextSettings { + return @bitCast(sf.c.sfContextSettings, self); + } + + pub fn _fromCSFML(context_settings: sf.c.sfContextSettings) ContextSettings { + return @bitCast(ContextSettings, context_settings); + } +};
\ No newline at end of file diff --git a/src/sfml/window/event.zig b/src/sfml/window/event.zig index c9694f1..a73c192 100644 --- a/src/sfml/window/event.zig +++ b/src/sfml/window/event.zig @@ -35,7 +35,7 @@ pub const Event = union(Event.Type) { // Big oof /// Creates this event from a csfml one - pub fn fromCSFML(event: sf.c.sfEvent) Self { + pub fn _fromCSFML(event: sf.c.sfEvent) Self { return switch (event.type) { sf.c.sfEvtClosed => .{ .closed = {} }, sf.c.sfEvtResized => .{ .resized = .{ .size = .{ .x = event.size.width, .y = event.size.height } } }, diff --git a/src/sfml/window/mouse.zig b/src/sfml/window/mouse.zig index c788324..b60ff00 100644 --- a/src/sfml/window/mouse.zig +++ b/src/sfml/window/mouse.zig @@ -15,12 +15,12 @@ pub fn isButtonPressed(button: Button) bool { /// Gets the position of the mouse cursor relative to the window passed or desktop pub fn getPosition(window: ?sf.graphics.RenderWindow) sf.system.Vector2i { if (window) |w| { - return sf.system.Vector2i.fromCSFML(sf.c.sfMouse_getPosition(@ptrCast(*sf.c.sfWindow, w.ptr))); - } else return sf.system.Vector2i.fromCSFML(sf.c.sfMouse_getPosition(null)); + return sf.system.Vector2i._fromCSFML(sf.c.sfMouse_getPosition(@ptrCast(*sf.c.sfWindow, w._ptr))); + } else return sf.system.Vector2i._fromCSFML(sf.c.sfMouse_getPosition(null)); } /// Set the position of the mouse cursor relative to the window passed or desktop pub fn setPosition(position: sf.system.Vector2i, window: ?sf.graphics.RenderWindow) void { if (window) |w| { - sf.c.sfMouse_setPosition(position.toCSFML(), @ptrCast(*sf.c.sfWindow, w.ptr)); - } else sf.c.sfMouse_setPosition(position.toCSFML(), null); + sf.c.sfMouse_setPosition(position._toCSFML(), @ptrCast(*sf.c.sfWindow, w._ptr)); + } else sf.c.sfMouse_setPosition(position._toCSFML(), null); } |
