1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 # Basic SDL 2 features
18 module sdl2_base
is pkgconfig
"sdl2"
25 # Access to the global methods of `sdl2`
26 var sdl
= new SDL is lazy
29 # Holds the global methods of `sdl2`
33 # Get the `SDL` singleton
34 new do return once
new SDL.internal
36 # TODO make this private and only called through `sys.sdl`
39 # Initialize the given SDL `subsystems`, returns `false` on error
40 fun initialize
(subsystems
: SDLInitFlags): Bool `{ return SDL_Init(subsystems) == 0; `}
42 # Returns the latest SDL error
44 # After calling this method, you should also call `clear_error
`.
45 fun error: CString `{ return (char*)SDL_GetError(); `}
48 fun clear_error
`{ SDL_ClearError(); `}
51 fun quit `{ SDL_Quit(); `}
53 # Was SDL initialized?
54 fun was_initialized
: Bool do return not initialized_subsystems
((new SDLInitFlags).everything
).is_empty
56 # What SDL subsystems are initialized? You can use a mask of `subsystems` to restrict the query.
58 # Returns the flags of the initialized subsystems.
59 fun initialized_subsystems
(subsystems
: SDLInitFlags): SDLInitFlags `{ return SDL_WasInit(subsystems); `}
61 # The number of CPU on the system
62 fun cpu_count: Int `{ return SDL_GetCPUCount(); `}
64 # Amount of RAM configured on the system
65 fun system_ram
: Int `{ return SDL_GetSystemRAM(); `}
67 # Show a simple message box
68 fun show_simple_message_box(level: SDLMessageBoxFlags, title, content: CString) `{
69 SDL_ShowSimpleMessageBox(level
, title
, content
, NULL);
72 redef fun finalize do if was_initialized then quit
74 # Function that should be called from the SDL main method
76 # This method should not normally be used, refer to the SDL source code
78 fun set_main_ready `{ SDL_SetMainReady(); `}
80 # Show or hide the cursor
81 fun show_cursor
=(val
: Bool) `{ SDL_ShowCursor(val? SDL_ENABLE: SDL_DISABLE); `}
83 # Is the cursor visible?
84 fun show_cursor: Bool `{ return SDL_ShowCursor(SDL_QUERY); `}
86 # Collect only relative mouse events and hide cursor
88 # Check `relative_mouse_mode` to see if the mode could be applied,
89 # if not, see `error`.
90 fun relative_mouse_mode
=(value
: Bool) `{
91 SDL_SetRelativeMouseMode(value);
94 # Hide cursor and collect only relative mouse events?
95 fun relative_mouse_mode
: Bool `{
96 return SDL_GetRelativeMouseMode();
100 # Flags for `sys.sdl.initialize` and related methods
101 extern class SDLInitFlags `{ Uint32 `}
102 # Get the default empty flag set
105 # Add the timer subsystem
106 fun timer
: SDLInitFlags `{ return self | SDL_INIT_TIMER; `}
108 # Add the audio subsystem
109 fun audio: SDLInitFlags `{ return self | SDL_INIT_AUDIO; `}
111 # Add the video subsystem
112 fun video
: SDLInitFlags `{ return self | SDL_INIT_VIDEO; `}
114 # Add the joystick subsystem
116 # Implied by `gamecontroller
`
117 fun joystick: SDLInitFlags `{ return self | SDL_INIT_JOYSTICK; `}
119 # Add the haptic subsystem
120 fun haptic
: SDLInitFlags `{ return self | SDL_INIT_HAPTIC; `}
122 # Add the gamecontroller subsystem
123 fun gamecontroller: SDLInitFlags `{ return self | SDL_INIT_GAMECONTROLLER; `}
125 # Add the events subsystem
127 # Implied by `video` and `joystick`
128 fun events
: SDLInitFlags `{ return self | SDL_INIT_EVENTS; `}
131 fun everything: SDLInitFlags `{ return self | SDL_INIT_EVERYTHING; `}
133 # Is this flag set empty?
134 fun is_empty
: Bool `{ return self == 0; `}
136 # TODO add all other is_
139 # A window created by SDL
140 extern class SDLWindow `{ SDL_Window * `}
141 # Create a window with the given `title`, `width` and `height`, also apply the `flags`
142 new (title
: CString, width
, height
: Int, flags
: SDLWindowFlags) `{
143 return SDL_CreateWindow(title,
144 SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
145 width, height, flags);
148 # Has this window been correctly initialized?
149 fun initialized
: Bool do return not address_is_null
151 # Destroy this window
152 fun destroy
`{ SDL_DestroyWindow(self); `}
154 # Get the `SDLWindowFlags` describing the status of the window
155 fun flags: SDLWindowFlags `{ return SDL_GetWindowFlags(self); `}
157 # Show a simple message box
159 # Similar to `sys.sdl.show_simple_message_box` but attached to this window
160 fun show_simple_message_box
(level
: SDLMessageBoxFlags, title
, content
: CString) `{
161 SDL_ShowSimpleMessageBox(level, title, content, self);
164 # Set the icon of this window
165 fun icon
=(icon
: SDLSurface) `{ SDL_SetWindowIcon(self, icon); `}
168 # Flags for `SDLWindow::new` and returned by `SDLWindow::flags
`
169 extern class SDLWindowFlags `{ Uint32 `}
170 # Get the default empty flag set
173 # Add the flag requesting a fullscreen window
174 fun fullscreen: SDLWindowFlags `{ return self | SDL_WINDOW_FULLSCREEN; `}
176 # Add the flag requesting a fullscreen window for the current desktop
177 fun fullscreen_desktop
: SDLWindowFlags `{ return self | SDL_WINDOW_FULLSCREEN_DESKTOP; `}
179 # Add the flag requesting a window usable with an OpenGL context
180 fun opengl: SDLWindowFlags `{ return self | SDL_WINDOW_OPENGL; `}
182 # Add the flag requesting a hidden window
183 fun hidden
: SDLWindowFlags `{ return self | SDL_WINDOW_HIDDEN; `}
185 # Add the flag requesting a borderless window
186 fun borderless: SDLWindowFlags `{ return self | SDL_WINDOW_BORDERLESS; `}
188 # Add the flag requesting a resizable window
189 fun resizable
: SDLWindowFlags `{ return self | SDL_WINDOW_RESIZABLE; `}
191 # Add the flag requesting a minimized window
192 fun minimized: SDLWindowFlags `{ return self | SDL_WINDOW_MINIMIZED; `}
194 # Add the flag requesting a maximimez window
195 fun maximized
: SDLWindowFlags `{ return self | SDL_WINDOW_MAXIMIZED; `}
197 # Add the flag to grab the input focus
198 fun input_grabbed: SDLWindowFlags `{ return self | SDL_WINDOW_INPUT_GRABBED; `}
200 # Add the flag to request a window using the system High-DPI mode
201 fun allow_highdpi
: SDLWindowFlags `{
202 #if SDL_VERSION_ATLEAST(2, 0, 2)
203 return self | SDL_WINDOW_ALLOW_HIGHDPI;
209 # Is the window shown?
211 # Can only be queried because it is ignored by `SDLWindow::new`
212 fun is_shown
: Bool `{ return self & SDL_WINDOW_SHOWN; `}
214 # Does the window has the input focus?
216 # Can only be queried because it is ignored by `SDLWindow::new`
217 fun has_input_focus: Bool `{ return self & SDL_WINDOW_INPUT_FOCUS; `}
219 # Does the window has the mouse focus?
221 # Can only be queried because it is ignored by `SDLWindow::new`
222 fun has_mouse_focus
: Bool `{ return self & SDL_WINDOW_MOUSE_FOCUS; `}
224 # TODO add all other `is_
` methods, as needed
228 # Suspend execution for `self` milliseconds
229 fun delay `{ SDL_Delay(self); `}
232 # A renderer, maybe software or hardware
233 extern class SDLRenderer `{ SDL_Renderer * `}
234 # Create a new `SDLRenderer` for the `window
` using the `index
`th renderer according to `flags
`
236 # Use an `index
` of `-1` to get the default renderer for the given flags.
237 new (window: SDLWindow, index: Int, flags: SDLRendererFlags) `{
238 return SDL_CreateRenderer(window
, index
, flags
);
241 # Create a new software `SDLRenderer`
242 new software(surface: SDLSurface) `{
243 return SDL_CreateSoftwareRenderer(surface
);
246 # Destroy this renderer
247 fun destroy `{ SDL_DestroyRenderer(self); `}
249 # Clear the rendering target with the current `draw_color`
250 fun clear
`{ SDL_RenderClear(self); `}
252 # Copy the rectangle at `src
` from `texture
` to fill the `dst
` at the rendering `target
`
254 # If `dst
` has a different size than `src
`, the image will be stretched.
256 # If `src
== null` the whole source texture will be drawn, and if
257 # `dst
== null` then the texture will fill the rendering `target
`.
258 fun copy(texture: SDLTexture, src, dst: nullable SDLRect)
260 if src == null then src = new SDLRect.nil
261 if dst == null then dst = new SDLRect.nil
263 native_copy(texture, src, dst)
266 private fun native_copy(texture: SDLTexture, src, dst: SDLRect) `{
267 SDL_RenderCopy(self, texture
, src
, dst
);
270 # Update the screen with all rendering since the previous call
271 fun present `{ SDL_RenderPresent(self); `}
273 # Get the `SDLRendererInfo` for this renderer
274 fun info_copy
(out
: SDLRendererInfo) `{ SDL_GetRendererInfo(self, out); `}
276 # Set the drawing color
277 fun draw_color=(val: SDLColor) `{
278 SDL_SetRenderDrawColor(self, val-
>r
, val-
>g
, val-
>b
, val-
>a
);
281 # Get the drawing color of this renderer
283 # The returned `SDLColor` is malloced here and must be freed by the called.
284 # For a more efficient usage, it is recommended to use instead `draw_color_copy
`.
285 fun draw_color: SDLColor
287 var color = new SDLColor.malloc
288 draw_color_copy color
292 # Copy the drawing color of this renderer in `color
`
293 fun draw_color_copy(color: SDLColor) `{
294 SDL_GetRenderDrawColor(self, &color-
>r
, &color-
>g
, &color-
>b
, &color-
>a
);
297 # Fill a rectangle with the current `draw_color
`
299 # If `rect
.address_is_null
` then fills the entire screen.
300 fun fill_rect(rect: SDLRect) `{ SDL_RenderFillRect(self, rect); `}
302 # Draw a rectangle with the current `draw_color`
303 fun draw_rect
(rect
: SDLRect) `{ SDL_RenderDrawRect(self, rect); `}
305 # Draw a point with the current `draw_color
`
306 fun draw_point(x, y: Int) `{ SDL_RenderDrawPoint(self, x, y); `}
308 # Draw a line with the current `draw_color`
309 fun draw_line
(x1
, y1
, x2
, y2
: Int) `{ SDL_RenderDrawLine(self, x1, y1, x2, y2); `}
311 # Set the viewport of this renderer
312 fun viewport=(rect: SDLRect) `{ SDL_RenderSetViewport(self, rect); `}
314 # Get the rendering target of this renderer
315 fun target
: SDLTexture `{ return SDL_GetRenderTarget(self); `}
317 # Set the rendering target of this renderer
318 fun target=(val: SDLTexture) `{ SDL_SetRenderTarget(self, val); `}
320 # TODO add other renderer related methods:
327 extern class SDLColor `{ SDL_Color *`}
328 # Allocate the memory for a new `SDLColor`, it must then be freed with `free
`
329 new malloc `{ return malloc(sizeof(SDL_Color)); `}
331 # Allocate the memory for a new `SDLColor` and fill it with `r`, `g`, `b` and `a`
333 # As with `malloc`, the new instances must then be freed with `free`.
334 new (r
, g
, b
, a
: Int)
336 var color
= new SDLColor.malloc
337 color
.set
(r
, g
, b
, a
)
341 # Set this instance's `r`, `g`, `b` and `a`
342 fun set
(r
, g
, b
, a
: Int)
350 # The red component of this color `[0..255]`
351 fun r
: Int `{ return self->r; `}
353 # Set the red component of this color `[0..255]`
354 fun r=(val: Int) `{ self->r = val; `}
356 # The green component of this color `[0..255]`
357 fun g
: Int `{ return self->g; `}
359 # Set the green component of this color `[0..255]`
360 fun g=(val: Int) `{ self->g = val; `}
362 # The blue component of this color `[0..255]`
363 fun b
: Int `{ return self->b; `}
365 # Set the blue component of this color `[0..255]`
366 fun b=(val: Int) `{ self->b = val; `}
368 # The alpha component of this color `[0..255]`
369 fun a
: Int `{ return self->a; `}
371 # Set the ralpha component of this color `[0..255]`
372 fun a=(val: Int) `{ self->a = val; `}
374 # TODO implement the related `SDL_Palette` and related methods
377 # Flags for `SDLRenderer::new`
378 extern class SDLRendererFlags `{ Uint32 `}
379 # Get the default empty flag set
382 # Add the flag to request a software renderer
383 fun software
: SDLRendererFlags `{ return self | SDL_RENDERER_SOFTWARE; `}
385 # Add the flag to request an accelerated renderer
387 # This is the default option.
388 fun accelerated: SDLRendererFlags `{ return self | SDL_RENDERER_ACCELERATED; `}
390 # Add the flag to request a renderer where `SDLRenderer::present` is synchronized with the refresh rate
391 fun presentvsync
: SDLRendererFlags `{ return self | SDL_RENDERER_PRESENTVSYNC; `}
393 # Add the flag to request a renderer able to render to a texture
394 fun targettexture: SDLRendererFlags `{ return self | SDL_RENDERER_TARGETTEXTURE; `}
398 extern class SDLSurface `{ SDL_Surface * `}
400 # Load the BMP file at `path
`
401 new load_bmp(path: CString) `{ return SDL_LoadBMP(path); `}
403 redef fun free
`{ SDL_FreeSurface(self); `}
405 # Save this texture to a BMP file
406 fun save_bmp(path: CString) `{ SDL_SaveBMP(self, path); `}
408 # Format of the pixels
409 fun format
: SDL_PixelFormat `{ return self->format; `}
412 fun w: Int `{ return self->w; `}
415 fun h
: Int `{ return self->h; `}
417 # Bytes in a row of pixels
418 fun pitch: Int `{ return self->pitch; `}
420 # Pointer to pixel data
421 fun pixels
: Pointer `{ return self->pixels; `}
424 # Pixel format information
425 extern class SDL_PixelFormat `{ SDL_PixelFormat * `}
426 # Number of significant bits in a pixel
427 fun bits_per_pixel
: Int `{ return self->BitsPerPixel; `}
429 # Number of bytes required to hold a pixel
430 fun bytes_per_pixel: Int `{ return self->BytesPerPixel; `}
432 # Mask of the location of the red component
433 fun rmask
: UInt32 `{ return self->Rmask; `}
435 # Mask of the location of the green component
436 fun gmask: UInt32 `{ return self->Gmask; `}
438 # Mask of the location of the blue component
439 fun bmask
: UInt32 `{ return self->Bmask; `}
441 # Mask of the location of the alpha component
442 fun amask: UInt32 `{ return self->Amask; `}
445 # A loaded bitmap texture
446 extern class SDLTexture `{ SDL_Texture * `}
447 # Get a `SDLTexture` from a `surface
`, for a given `renderer
`
448 new from_surface(renderer: SDLRenderer, surface: SDLSurface) `{
449 return SDL_CreateTextureFromSurface(renderer
, surface
);
452 # Destroy this texture
453 fun destroy `{ SDL_DestroyTexture(self); `}
455 # Width of this texture
458 SDL_QueryTexture(self, NULL, NULL, &val, NULL);
462 # Height of this texture
465 SDL_QueryTexture(self, NULL, NULL, NULL, &val);
469 # TODO other queries: format and access
473 extern class SDLRect `{SDL_Rect *`}
474 # Get a null rectangle (on the C side), should be used only internally
475 new nil `{ return NULL; `}
477 # Allocate the memory for a new `SDLRect`, it must then be freed with `free`
478 new malloc
`{ return malloc(sizeof(SDL_Rect)); `}
480 # Allocate the memory for a new `SDLRect` and fill it with `x
`, `y
`, `w
` and `h
`
482 # As with `malloc
`, the new instances must then be freed with `free
`.
483 new (x, y, w, h: Int)
485 var rect = new SDLRect.malloc
490 # Set this instance's `x
`, `y
`, `w
` and `h
`
491 fun set(x, y, w, h: Int)
499 # X coordinate of the top left corner
500 fun x: Int `{ return self->x; `}
502 # Set the X coordinate of the top left corner
503 fun x
=(val
: Int) `{ self->x = val; `}
505 # Y coordinate of the top left corner
506 fun y: Int `{ return self->y; `}
508 # Set the Y coordinate of the top left corner
509 fun y
=(val
: Int) `{ self->y = val; `}
511 # Width of this rectangle
512 fun w: Int `{ return self->w; `}
514 # Set the width of this rectangle
515 fun w
=(val
: Int) `{ self->w = val; `}
517 # Height of this rectangle
518 fun h: Int `{ return self->h; `}
520 # Set the height of this rectangle
521 fun h
=(val
: Int) `{ self->h = val; `}
523 # TODO implement other `SDLRect` related methods:
526 # SDL_HasIntersection
528 # SDL_IntersectRectAndLine
535 # A point with `x
` and `y
`
536 extern class SDLPoint `{SDL_Point *`}
537 # Get a null rectangle (on the C side), should be used only internally
538 new nil
`{ return NULL; `}
540 # Allocate the memory for a new `SDLPoint`, it must the be freed with `free
`
541 new malloc`{ return malloc(sizeof(SDL_Point)); `}
543 # Allocate the memory for a new `SDLPoint` and fill it with `x` and `y`
545 # As with `malloc`, the new instances must the be freed with `free`.
547 var point
= new SDLPoint.malloc
553 # X coordinate of this point
554 fun x
: Int `{ return self->x; `}
556 # Set the X coordinate of this point
557 fun x=(val: Int) `{ self->x = val; `}
559 # Y coordinate of this point
560 fun y
: Int `{ return self->y; `}
562 # Set the Y coordinate of this point
563 fun y=(val: Int) `{ self->y = val; `}
566 # Flag to set the icon in `sys.sdl.show_simple_message_box` and `SDLWindow::show_simple_message_box`
567 extern class SDLMessageBoxFlags `{ Uint32 `}
568 # Request the error icon
569 new error `{ return SDL_MESSAGEBOX_ERROR; `}
571 # Request the warning icon
572 new warning
`{ return SDL_MESSAGEBOX_WARNING; `}
574 # Request the information icon
575 new information `{ return SDL_MESSAGEBOX_INFORMATION; `}
578 # Information on a `SDLRenderer`
579 extern class SDLRendererInfo `{ SDL_RendererInfo * `}
580 # Allocate the memory for a new `SDLRenderer`, it must then be freed with `free
`
581 new malloc `{ return malloc(sizeof(SDL_RendererInfo)); `}
583 # Name of the renderer's driver
584 fun name
: CString `{ return (char*)self->name; `}
586 # Maximum texture width supported by the renderer
587 fun max_texture_width: Int `{ return self->max_texture_width; `}
589 # Maximum texture height supported by the renderer
590 fun max_texture_height
: Int `{ return self->max_texture_height; `}