examples: annotate examples
[nit.git] / lib / sdl.nit
index 26ae459..7eae171 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# SDL display support (used in Linux for windows and inputes only)
+# Simple DirectMedia Layer
 module sdl is
-       c_compiler_option(exec("sdl-config", "--cflags"))
-       c_linker_option(exec("sdl-config", "--libs"), "-lSDL_image -lSDL_ttf")
+       cflags exec("sdl-config", "--cflags")
+       ldflags(exec("sdl-config", "--libs"), "-lSDL_image -lSDL_ttf")
 end
 
-import mnit_display
+import mnit::display
+import c
 
 in "C header" `{
        #include <unistd.h>
@@ -69,27 +70,27 @@ extern class SDLDisplay `{SDL_Surface *`}
                        TTF_Quit();
        `}
 
-       redef fun finish `{ SDL_Flip(recv); `}
+       redef fun finish `{ SDL_Flip(self); `}
 
        # Clear the entire window with given RGB color (integer values)
        fun clear_int(r, g, b: Int) `{
-               SDL_FillRect(recv, NULL, SDL_MapRGB(recv->format,r,g,b)); 
+               SDL_FillRect(self, NULL, SDL_MapRGB(self->format,r,g,b));
        `}
 
-       redef fun width: Int `{ return recv->w; `}
-       redef fun height: Int `{ return recv->h; `}
+       redef fun width `{ return self->w; `}
+       redef fun height `{ return self->h; `}
 
        # Fill a rectangle with given color
        fun fill_rect(rect: SDLRectangle, r, g, b: Int) `{
-               SDL_FillRect(recv, rect,  SDL_MapRGB(recv->format,r,g,b));
+               SDL_FillRect(self, rect,  SDL_MapRGB(self->format,r,g,b));
        `}
 
-       redef fun clear(r, g, b: Float) `{
+       redef fun clear(r, g, b) `{
                Uint8 ri, gi, bi;
                ri = (Uint8)r*255;
                gi = (Uint8)g*255;
                bi = (Uint8)b*255;
-               SDL_FillRect(recv, NULL, SDL_MapRGB(recv->format,ri,gi,bi));
+               SDL_FillRect(self, NULL, SDL_MapRGB(self->format,ri,gi,bi));
        `}
 
        # SDL events since the last call to this method
@@ -104,58 +105,53 @@ extern class SDLDisplay `{SDL_Surface *`}
                return events
        end
 
-       private fun poll_event: nullable SDLInputEvent import SDLKeyEvent, SDLMouseButtonEvent, SDLMouseMotionEvent, SDLQuitEvent, NativeString.to_s, SDLMouseButtonEvent.as(nullable SDLInputEvent), SDLMouseMotionEvent.as(nullable SDLInputEvent), SDLKeyEvent.as(nullable SDLInputEvent), SDLQuitEvent.as(nullable SDLInputEvent) `{
-               SDL_Event event;
-
+       private fun poll_event: nullable SDLInputEvent
+       import new_key_event, new_mouse_motion_event, new_mouse_button_event, new_quit_event `{
                SDL_PumpEvents();
 
+               SDL_Event event;
                if (SDL_PollEvent(&event))
                {
                        switch (event.type) {
                                case SDL_KEYDOWN:
                                case SDL_KEYUP:
-       #ifdef DEBUG
-                                       printf("The \"%s\" key was pressed!\n",
-                                                  SDL_GetKeyName(event.key.keysym.sym));
-       #endif
-
-                                       return SDLKeyEvent_as_nullable_SDLInputEvent(
-                                                       new_SDLKeyEvent(NativeString_to_s(
-                                                               SDL_GetKeyName(event.key.keysym.sym)),
-                                                               event.type==SDL_KEYDOWN));
+                                       return SDLDisplay_new_key_event(self,
+                                                               SDL_GetKeyName(event.key.keysym.sym),
+                                                               event.type==SDL_KEYDOWN);
 
                                case SDL_MOUSEMOTION:
-       #ifdef DEBUG
-                                       printf("Mouse moved by %d,%d to (%d,%d)\n",
-                                                  event.motion.xrel, event.motion.yrel,
-                                                  event.motion.x, event.motion.y);
-       #endif
-
-                                       return SDLMouseMotionEvent_as_nullable_SDLInputEvent(
-                                                       new_SDLMouseMotionEvent(event.motion.x, event.motion.y,
-                                                               event.motion.xrel, event.motion.yrel, SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(1)));
+                                       return SDLDisplay_new_mouse_motion_event(self,
+                                               event.motion.x, event.motion.y,
+                                               event.motion.xrel, event.motion.yrel,
+                                               SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(1));
 
                                case SDL_MOUSEBUTTONDOWN:
                                case SDL_MOUSEBUTTONUP:
-       #ifdef DEBUG
-                                       printf("Mouse button \"%d\" pressed at (%d,%d)\n",
-                                                  event.button.button, event.button.x, event.button.y);
-       #endif
-                                       return SDLMouseButtonEvent_as_nullable_SDLInputEvent(
-                                                       new_SDLMouseButtonEvent(event.button.x, event.button.y,
-                                                               event.button.button, event.type == SDL_MOUSEBUTTONDOWN));
+                                       return SDLDisplay_new_mouse_button_event(self,
+                                               event.button.x, event.button.y,
+                                               event.button.button,
+                                               event.type == SDL_MOUSEBUTTONDOWN);
 
                                case SDL_QUIT:
-       #ifdef DEBUG
-                                       printf("Quit event\n");
-       #endif
-                                       return SDLQuitEvent_as_nullable_SDLInputEvent(new_SDLQuitEvent());
+                                       return SDLDisplay_new_quit_event(self);
                        }
                }
 
                return null_SDLInputEvent();
        `}
 
+       private fun new_key_event(name: CString, down: Bool): nullable SDLInputEvent
+       do return new SDLKeyEvent(name.to_s, down)
+
+       private fun new_mouse_motion_event(x, y, xr, yr: Float, down: Bool): nullable SDLInputEvent
+       do return new SDLMouseMotionEvent(x, y, xr, yr, down)
+
+       private fun new_mouse_button_event(x, y: Float, id: Int, down: Bool): nullable SDLInputEvent
+       do return new SDLMouseButtonEvent(x, y, id, down)
+
+       private fun new_quit_event: nullable SDLInputEvent
+       do return new SDLQuitEvent
+
        # Set the position of the cursor to x,y
        fun warp_mouse(x,y: Int) `{ SDL_WarpMouse(x, y); `}
 
@@ -163,13 +159,13 @@ extern class SDLDisplay `{SDL_Surface *`}
        fun show_cursor=(val: Bool) `{ SDL_ShowCursor(val? SDL_ENABLE: SDL_DISABLE); `}
 
        # Is the cursor visible?
-       fun show_cursor: Bool `{ SDL_ShowCursor(SDL_QUERY); `}
+       fun show_cursor: Bool `{ return SDL_ShowCursor(SDL_QUERY); `}
 
        # Grab or release the input
        fun grab_input=(val: Bool) `{ SDL_WM_GrabInput(val? SDL_GRAB_ON: SDL_GRAB_OFF); `}
 
        # Is the input grabbed?
-       fun grab_input: Bool `{ SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON; `}
+       fun grab_input: Bool `{ return SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON; `}
 
        # Are instances of `SDLMouseMotionEvent` ignored?
        fun ignore_mouse_motion_events: Bool `{
@@ -180,6 +176,12 @@ extern class SDLDisplay `{SDL_Surface *`}
        fun ignore_mouse_motion_events=(val: Bool) `{
                SDL_EventState(SDL_MOUSEMOTION, val? SDL_IGNORE: SDL_ENABLE);
        `}
+
+       # Does `self` has the mouse focus?
+       fun mouse_focus: Bool `{ return SDL_GetAppState() & SDL_APPMOUSEFOCUS; `}
+
+       # Does `self` has the input focus?
+       fun input_focus: Bool `{ return SDL_GetAppState() & SDL_APPINPUTFOCUS; `}
 end
 
 # Basic Drawing figures
@@ -196,7 +198,7 @@ extern class SDLDrawable `{SDL_Surface*`}
                dst.w = 0;
                dst.h = 0;
 
-               SDL_BlitSurface(img, NULL, recv, &dst);
+               SDL_BlitSurface(img, NULL, self, &dst);
        `}
 
        redef fun blit_centered(img, x, y)
@@ -238,12 +240,18 @@ extern class SDLImage
        fun save_to_file(path: String) import String.to_cstring `{ `}
 
        # Destroy the image and free the memory
-       redef fun destroy `{ SDL_FreeSurface(recv); `}
+       redef fun destroy `{ SDL_FreeSurface(self); `}
 
-       redef fun width: Int `{ return recv->w; `}
-       redef fun height: Int `{ return recv->h; `}
+       redef fun width `{ return self->w; `}
+       redef fun height `{ return self->h; `}
 
        fun is_ok: Bool do return not address_is_null
+
+       # Returns a reference to the pixels of the texture
+       fun pixels: NativeCByteArray `{ return self->pixels; `}
+
+       # Mask for the alpha value of each pixel
+       fun amask: Int `{ return self->format->Amask; `}
 end
 
 # A simple rectangle
@@ -258,17 +266,17 @@ extern class SDLRectangle `{SDL_Rect*`}
                return rect;
        `}
 
-       fun x=(v: Int) `{ recv->x = (Sint16)v; `}
-       fun x: Int `{ return recv->x; `}
+       fun x=(v: Int) `{ self->x = (Sint16)v; `}
+       fun x: Int `{ return self->x; `}
 
-       fun y=(v: Int) `{ recv->y = (Sint16)v; `}
-       fun y: Int `{ return recv->y; `}
+       fun y=(v: Int) `{ self->y = (Sint16)v; `}
+       fun y: Int `{ return self->y; `}
 
-       fun w=(v: Int) `{ recv->w = (Uint16)v; `}
-       fun w: Int `{ return recv->w; `}
+       fun w=(v: Int) `{ self->w = (Uint16)v; `}
+       fun w: Int `{ return self->w; `}
 
-       fun h=(v: Int) `{ recv->h = (Uint16)v; `}
-       fun h: Int `{ return recv->h; `}
+       fun h=(v: Int) `{ self->h = (Uint16)v; `}
+       fun h: Int `{ return self->h; `}
 end
 
 interface SDLInputEvent
@@ -280,14 +288,10 @@ class SDLMouseEvent
        super PointerEvent
        super SDLInputEvent
 
-       redef var x: Float
-       redef var y: Float
+       redef var x
+       redef var y
 
-       private init (x, y: Float)
-       do
-               self.x = x
-               self.y = y
-       end
+       redef fun is_move do return false
 end
 
 # MouseButtonEvent used to get information when a button is pressed/depressed
@@ -296,17 +300,16 @@ class SDLMouseButtonEvent
 
        var button: Int
 
-       redef var pressed: Bool
-       redef fun depressed: Bool do return not pressed
+       redef var pressed
 
        # Is this event raised by the left button?
        fun is_left_button: Bool do return button == 1
 
        # Is this event raised by the right button?
-       fun is_right_button: Bool do return button == 2
+       fun is_right_button: Bool do return button == 3
 
        # Is this event raised by the middle button?
-       fun is_middle_button: Bool do return button == 3
+       fun is_middle_button: Bool do return button == 2
 
        # Is this event raised by the wheel going down?
        fun is_down_wheel: Bool do return button == 4
@@ -342,8 +345,9 @@ class SDLMouseMotionEvent
        var rel_x: Float
        var rel_y: Float
 
-       redef var pressed: Bool
-       redef fun depressed: Bool do return not pressed
+       redef var pressed
+
+       redef fun is_move do return true
 
        init (x, y, rel_x, rel_y: Float, pressed: Bool)
        do
@@ -362,27 +366,22 @@ class SDLKeyEvent
        super KeyEvent
        super SDLInputEvent
 
-       var key_name: String
-       var down: Bool
+       redef var name
 
-       init (key_name: String, down: Bool)
-       do
-               self.key_name = key_name
-               self.down = down
-       end
+       var down: Bool
 
-       redef fun to_c: nullable Char
+       redef fun to_c
        do
-               if key_name.length == 1 then return key_name.chars.first
+               if name.length == 1 then return name.chars.first
                return null
        end
 
        redef fun to_s
        do
                if down then
-                       return "KeyboardEvent key {key_name} down"
+                       return "KeyboardEvent key {name} down"
                else
-                       return "KeyboardEvent key {key_name} up"
+                       return "KeyboardEvent key {name} up"
                end
        end
 
@@ -390,13 +389,16 @@ class SDLKeyEvent
        redef fun is_down do return down
 
        # Return true if the key is the up arrow
-       redef fun is_arrow_up do return key_name == "up"
+       redef fun is_arrow_up do return name == "up"
+
        # Return true if the key is the left arrow
-       redef fun is_arrow_left do return key_name == "left"
+       redef fun is_arrow_left do return name == "left"
+
        # Return true if the key is the down arrow
-       redef fun is_arrow_down do return key_name == "down"
+       redef fun is_arrow_down do return name == "down"
+
        # Return true if the key is the right arrow
-       redef fun is_arrow_right do return key_name == "right"
+       redef fun is_arrow_right do return name == "right"
 end
 
 class SDLQuitEvent
@@ -405,7 +407,7 @@ class SDLQuitEvent
 end
 
 redef class Int
-       fun delay `{ SDL_Delay(recv); `}
+       fun delay `{ SDL_Delay(self); `}
 end
 
 # Class to load and use TTF_Font
@@ -423,7 +425,7 @@ extern class SDLFont `{TTF_Font *`}
        return font;
        `}
 
-       fun destroy `{ TTF_CloseFont(recv); `}
+       fun destroy `{ TTF_CloseFont(self); `}
 
        # Create a String with the specified color, return an SDLImage
        fun render(text: String, r, g, b: Int): SDLImage import String.to_cstring `{
@@ -436,7 +438,7 @@ extern class SDLFont `{TTF_Font *`}
                color.b = b;
 
                ctext = String_to_cstring(text);
-               if(!(text_surface=TTF_RenderText_Blended(recv, ctext, color)))
+               if(!(text_surface=TTF_RenderText_Blended(self, ctext, color)))
                {
                        fprintf(stderr, "SDL TFF error: %s\n", TTF_GetError());
                        exit(1);
@@ -454,52 +456,52 @@ extern class SDLFont `{TTF_Font *`}
 
        # Maximum pixel height of all glyphs of this font.
        fun height: Int `{
-               return TTF_FontHeight(recv);
+               return TTF_FontHeight(self);
        `}
 
        fun ascent: Int `{
-               return TTF_FontAscent(recv);
+               return TTF_FontAscent(self);
        `}
 
        fun descent: Int `{
-               return TTF_FontDescent(recv);
+               return TTF_FontDescent(self);
        `}
 
        # Get the recommended pixel height of a rendered line of text of the loaded font. This is usually larger than the Font.height.
        fun line_skip: Int `{
-               return TTF_FontLineSkip(recv);
+               return TTF_FontLineSkip(self);
        `}
 
        # Return true is the font used fixed width for each char
        fun is_fixed_width: Bool `{
-               return TTF_FontFaceIsFixedWidth(recv);
+               return TTF_FontFaceIsFixedWidth(self);
        `}
 
        # Return the family name of the font
        fun family_name: nullable String import String.to_cstring, String.as nullable  `{
-               char *fn = TTF_FontFaceFamilyName(recv);
+               char *fn = TTF_FontFaceFamilyName(self);
 
                if (fn == NULL)
                        return null_String();
                else
-                       return String_as_nullable(NativeString_to_s(fn));
+                       return String_as_nullable(CString_to_s(fn));
        `}
 
        # Return the style name of the font
        fun style_name: nullable String import String.to_cstring, String.as nullable  `{
-               char *sn = TTF_FontFaceStyleName(recv);
+               char *sn = TTF_FontFaceStyleName(self);
 
                if (sn == NULL)
                        return null_String();
                else
-                       return String_as_nullable(NativeString_to_s(sn));
+                       return String_as_nullable(CString_to_s(sn));
        `}
 
        # Return the estimated width of a String if used with the current font
-       fun width_of(text: String): Int import NativeString.to_s `{
+       fun width_of(text: String): Int import CString.to_s `{
                char *ctext = String_to_cstring(text);
                int w;
-               if (TTF_SizeText(recv, ctext, &w, NULL))
+               if (TTF_SizeText(self, ctext, &w, NULL))
                {
                        fprintf(stderr, "SDL TFF error: %s\n", TTF_GetError());
                        exit(1);
@@ -528,6 +530,6 @@ extern class SDLSystemWindowManagerInfo `{SDL_SysWMinfo *`}
 
        # Returns the handle of this window on a X11 window system
        fun x11_window_handle: Pointer `{
-               return (void*)recv->info.x11.window;
+               return (void*)self->info.x11.window;
        `}
 end