gamnit: enable dynamic window resizing on desktop
[nit.git] / lib / gamnit / display_linux.nit
index e79d22f..15f5281 100644 (file)
@@ -15,8 +15,8 @@
 # Gamnit display implementation for GNU/Linux using `egl`, `sdl` and `x11`
 module display_linux
 
-import sdl
-import x11
+import sdl2::image
+import sdl2::mixer
 
 import egl # local to gamnit
 intrude import display
@@ -32,20 +32,22 @@ redef class GamnitDisplay
        fun height=(value: Int) do requested_height = value
        private var requested_height = 1080
 
-       # Setup SDL, X11, EGL in order
+       redef fun show_cursor do return sdl.show_cursor
+
+       redef fun show_cursor=(val) do sdl.show_cursor = val
+
+       # Setup SDL, wm, EGL in order
        redef fun setup
        do
                if debug_gamnit then print "Setting up SDL"
-               self.sdl_display = setup_sdl(requested_width, requested_height)
+               self.sdl_window = setup_sdl(requested_width, requested_height)
 
-               if debug_gamnit then print "Setting up X11"
-               var x11_display = setup_x11
-               var window_handle = window_handle
-               setup_egl_display x11_display
+               if debug_gamnit then print "Setting up window manager"
+               setup_egl_display sdl_window.wm_info.display_handle
 
                if debug_gamnit then print "Setting up EGL context"
-               select_egl_config(8, 8, 8, 8, 8, 0, 0)
-               setup_egl_context window_handle
+               select_egl_config(red_bits, green_bits, blue_bits, 8, 8, 0, 0)
+               setup_egl_context sdl_window.wm_info.window_handle
        end
 
        # Close EGL and SDL in reverse order of `setup` (nothing to do for X11)
@@ -59,55 +61,79 @@ redef class GamnitDisplay
        # SDL
 
        # The SDL display managing the window and events
-       var sdl_display: SDLDisplay is noautoinit
+       var sdl_window: SDLWindow is noautoinit
+
+       # Title of the window, must be set before creating the window (or redef)
+       var window_title = "gamnit game" is lazy, writable
 
        # Setup the SDL display and lib
-       fun setup_sdl(window_width, window_height: Int): SDLDisplay
+       fun setup_sdl(window_width, window_height: Int): SDLWindow
        do
-               var sdl_display = new SDLDisplay(window_width, window_height)
-               assert not sdl_display.address_is_null else print "Opening SDL display failed"
-               return sdl_display
-       end
+               assert sdl.initialize((new SDLInitFlags).video.audio) else
+                       print_error "Failed to initialize SDL2: {sdl.error}"
+               end
 
-       # Close the SDL display
-       fun close_sdl do sdl_display.destroy
+               var img_flags = (new SDLImgInitFlags).png.jpg
+               assert sdl.img.initialize(img_flags) == img_flags else
+                       print_error "Failed to initialize SDL2 IMG: {sdl.error}"
+               end
 
-       # Get a native handle to the current SDL window
-       fun window_handle: Pointer
-       do
-               var sdl_wm_info = new SDLSystemWindowManagerInfo
-               return sdl_wm_info.x11_window_handle
+               var sdl_window = new SDLWindow(window_title.to_cstring, window_width, window_height, sdl_window_flags)
+               assert not sdl_window.address_is_null else
+                       print_error "Failed to create SDL2 window: {sdl.error}"
+               end
+
+               # Audio support
+               var inited = mix.initialize(mix_init_flags)
+               assert inited != mix_init_flags else
+                       print_error "Failed to load SDL2 mixer format supports: {mix.error}"
+               end
+
+               var opened = mix.open_audio(44100, mix.default_format, 2, 1024)
+               assert opened else
+                       print_error "Failed to initialize SDL2 mixer: {mix.error}"
+               end
+
+               return sdl_window
        end
 
-       # ---
-       # X11
+       # SDL2 window initialization flags
+       #
+       # The default value supports OpenGL and window resizing.
+       var sdl_window_flags: SDLWindowFlags = (new SDLWindowFlags).opengl.resizable is lazy, writable
 
-       # Get a native handle to the current X11 display
-       fun setup_x11: Pointer
+       # SDL2 mixer initialization flags
+       #
+       # Defaults to all available formats.
+       var mix_init_flags: MixInitFlags = mix.flac | mix.mod | mix.mp3 | mix.ogg is lazy, writable
+
+       # Close the SDL display
+       fun close_sdl
        do
-               var x11_display = x_open_default_display
-               assert not x11_display.address_is_null else print "Opening X11 display failed"
-               return x11_display
+               sdl_window.destroy
+               mix.close_audio
+               mix.quit
+               sdl.finalize
        end
 end
 
-redef class GamnitAssetTexture
+redef class TextureAsset
 
        redef fun load_from_platform
        do
-               var path = "assets" / path # TODO use app.assets_dir
-               var sdl_tex = new SDLImage.from_file(path)
+               var path = "assets" / path
 
-               if sdl_tex.address_is_null then
+               var surface = new SDLSurface.load(path.to_cstring)
+               if surface.address_is_null then
                        error = new Error("Failed to load texture at '{path}'")
                        return
                end
 
-               self.width = sdl_tex.width.to_f
-               self.height = sdl_tex.height.to_f
-               var format = if sdl_tex.amask > 0 then gl_RGBA else gl_RGB
-               var pixels = sdl_tex.pixels
+               self.width = surface.w.to_f
+               self.height = surface.h.to_f
+               var format = if surface.format.amask > 0u32 then gl_RGBA else gl_RGB
+               var pixels = surface.pixels
 
-               load_from_pixels(pixels, sdl_tex.width, sdl_tex.height, format)
+               load_from_pixels(pixels, surface.w, surface.h, format)
        end
 end