1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
//! Window that can serve as a target for 2D drawing.
const sf = struct {
pub usingnamespace @import("../sfml.zig");
pub usingnamespace sf.system;
pub usingnamespace sf.graphics;
pub usingnamespace sf.window;
};
const RenderWindow = @This();
// Constructor/destructor
/// 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, settings: ?sf.ContextSettings) !RenderWindow {
var ret: RenderWindow = undefined;
var mode: sf.c.sfVideoMode = .{
.width = @intCast(c_uint, size.x),
.height = @intCast(c_uint, size.y),
.bitsPerPixel = @intCast(c_uint, bpp),
};
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;
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 {
var ret: RenderWindow = undefined;
var mode: sf.c.sfVideoMode = .{
.width = @intCast(c_uint, size.x),
.height = @intCast(c_uint, size.y),
.bitsPerPixel = 32,
};
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;
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);
}
// Event related
/// Returns true if this window is still open
pub fn isOpen(self: RenderWindow) bool {
return sf.c.sfRenderWindow_isOpen(self._ptr) != 0;
}
/// Closes this window
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 {
var event: sf.c.sfEvent = undefined;
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);
}
// 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());
}
/// Displays what has been drawn on the render area
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.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).");
}
// 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).?);
}
/// 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).?);
}
/// Sets the view of this window
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);
}
/// 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));
}
/// Sets the size of this window
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));
}
/// Sets the position of this window
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);
}
/// Sets the windows's framerate limit
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_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();
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));
}
/// 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();
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));
}
/// Pointer to the csfml structure
_ptr: *sf.c.sfRenderWindow
|