X-Git-Url: http://nitlanguage.org diff --git a/lib/sdl.nit b/lib/sdl.nit index 806b07b..7eae171 100644 --- a/lib/sdl.nit +++ b/lib/sdl.nit @@ -14,13 +14,14 @@ # 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 @@ -69,101 +70,118 @@ 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 fun events: Sequence[SDLInputEvent] do - var new_event: nullable Object = null - var events = new List[SDLInputEvent] + var events = new Array[SDLInputEvent] loop - new_event = poll_event - if new_event != null then # new_event isa Event then # - events.add(new_event) - else - break - end + var new_event = poll_event + if new_event == null then break + events.add new_event end 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); `} # Show or hide the cursor - fun show_cursor(show: Bool) `{ SDL_ShowCursor(show); `} + fun show_cursor=(val: Bool) `{ SDL_ShowCursor(val? SDL_ENABLE: SDL_DISABLE); `} + + # Is the cursor visible? + 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 `{ return SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON; `} + + # Are instances of `SDLMouseMotionEvent` ignored? + fun ignore_mouse_motion_events: Bool `{ + return SDL_EventState(SDL_MOUSEMOTION, SDL_QUERY); + `} + + # Do not raise instances of `SDLMouseMotionEvent` if `val` + 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 @@ -180,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) @@ -222,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 @@ -242,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 @@ -264,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 @@ -280,8 +300,25 @@ 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 == 3 + + # Is this event raised by the middle button? + 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 + + # Is this event raised by the wheel going up? + fun is_up_wheel: Bool do return button == 5 + + # Is this event raised by the wheel? + fun is_wheel: Bool do return is_down_wheel or is_up_wheel init (x, y: Float, button: Int, pressed: Bool) do @@ -308,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 @@ -328,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 @@ -356,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 @@ -371,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 @@ -389,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 `{ @@ -402,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); @@ -420,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); @@ -494,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