634656b0fef68c9070ad01beaa2f6ae21c8a1541
[nit.git] / lib / gamnit / display_linux.nit
1 # This file is part of NIT (http://www.nitlanguage.org).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Gamnit display implementation for GNU/Linux using `egl`, `sdl` and `x11`
16 module display_linux
17
18 import sdl2::image
19 import sdl2::mixer
20
21 import egl # local to gamnit
22 intrude import display
23 intrude import textures
24
25 redef class GamnitDisplay
26
27 # Actual width or desired width of the window, can be set before calling `setup`
28 fun width=(value: Int) do requested_width = value
29 private var requested_width = 1920
30
31 # Actual height or desired height of the window, can be set before calling `setup`
32 fun height=(value: Int) do requested_height = value
33 private var requested_height = 1080
34
35 redef fun show_cursor do return sdl.show_cursor
36
37 redef fun show_cursor=(val) do sdl.show_cursor = val
38
39 # Setup SDL, wm, EGL in order
40 redef fun setup
41 do
42 if debug_gamnit then print "Setting up SDL"
43 self.sdl_window = setup_sdl(requested_width, requested_height)
44
45 if debug_gamnit then print "Setting up window manager"
46 setup_egl_display sdl_window.wm_info.display_handle
47
48 if debug_gamnit then print "Setting up EGL context"
49 select_egl_config(red_bits, green_bits, blue_bits, 8, 8, 0, 0)
50 setup_egl_context sdl_window.wm_info.window_handle
51 end
52
53 # Close EGL and SDL in reverse order of `setup` (nothing to do for X11)
54 redef fun close
55 do
56 close_egl
57 close_sdl
58 end
59
60 # ---
61 # SDL
62
63 # The SDL display managing the window and events
64 var sdl_window: SDLWindow is noautoinit
65
66 # Title of the window, must be set before creating the window (or redef)
67 var window_title = "gamnit game" is lazy, writable
68
69 # Setup the SDL display and lib
70 fun setup_sdl(window_width, window_height: Int): SDLWindow
71 do
72 assert sdl.initialize((new SDLInitFlags).video.audio) else
73 print_error "Failed to initialize SDL2: {sdl.error}"
74 end
75
76 var img_flags = (new SDLImgInitFlags).png.jpg
77 assert sdl.img.initialize(img_flags) == img_flags else
78 print_error "Failed to initialize SDL2 IMG: {sdl.error}"
79 end
80
81 var sdl_window = new SDLWindow(window_title.to_cstring, window_width, window_height, (new SDLWindowFlags).opengl)
82 assert not sdl_window.address_is_null else
83 print_error "Failed to create SDL2 window: {sdl.error}"
84 end
85
86 # Audio support
87 var inited = mix.initialize(mix_init_flags)
88 assert inited != mix_init_flags else
89 print_error "Failed to load SDL2 mixer format supports: {mix.error}"
90 end
91
92 var opened = mix.open_audio(44100, mix.default_format, 2, 1024)
93 assert opened else
94 print_error "Failed to initialize SDL2 mixer: {mix.error}"
95 end
96
97 return sdl_window
98 end
99
100 # Initialization flags passed to SDL2 mixer
101 #
102 # Defaults to all available formats.
103 var mix_init_flags: MixInitFlags = mix.flac | mix.mod | mix.mp3 | mix.ogg is lazy, writable
104
105 # Close the SDL display
106 fun close_sdl
107 do
108 sdl_window.destroy
109 mix.close_audio
110 mix.quit
111 sdl.finalize
112 end
113 end
114
115 redef class TextureAsset
116
117 redef fun load_from_platform
118 do
119 var path = "assets" / path
120
121 var surface = new SDLSurface.load(path.to_cstring)
122 if surface.address_is_null then
123 error = new Error("Failed to load texture at '{path}'")
124 return
125 end
126
127 self.width = surface.w.to_f
128 self.height = surface.h.to_f
129 var format = if surface.format.amask > 0u32 then gl_RGBA else gl_RGB
130 var pixels = surface.pixels
131
132 load_from_pixels(pixels, surface.w, surface.h, format)
133 end
134 end