-- -- SHOWIMAGE: Port to the Ada programming language of a test application for the -- the SDL image library. -- -- The original code was written in C by Sam Lantinga http://www.libsdl.org. -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- -- Ada code written by: -- Antonio M. F. Vargas -- -- Ponta Delgada - Azores - Portugal -- -- E-mail: avargas@adapower.net -- -- http://www.adapower.net/~avargas -- with System; with Interfaces.C.Strings; with Ada.Command_Line; with Ada.Text_IO; use Ada.Text_IO; with GNAT.OS_Lib; with SDL.Video; with SDL.Types; use SDL.Types; with SDL.Byteorder; with SDL.Byteorder.Extra; with SDL.Quit; with SDL.Error; with SDL.Events; with SDL_Image; procedure ShowImage is package C renames Interfaces.C; use type C.int; package It renames Interfaces; use type It.Unsigned_32; package CL renames Ada.Command_Line; package CS renames Interfaces.C.Strings; package V renames SDL.Video; use type V.Palette_ptr; use type V.Surface_ptr; use type V.Surface_Flags; package Er renames SDL.Error; package Ev renames SDL.Events; use type Ev.Event_Type; package IMG renames SDL_Image; -- Draw a Gimpish background pattern to show transparency in the image -- ====================================== procedure draw_background (screen : V.Surface_ptr) is use Uint8_PtrOps; use Uint8_Ptrs; use Uint16_PtrOps; use Uint16_Ptrs; use Uint32_PtrOps; use Uint32_Ptrs; use SDL.Byteorder; use SDL.Byteorder.Extra; package It renames Interfaces; dst : System.Address := screen.pixels; bpp : C.int := C.int (screen.format.BytesPerPixel); type col_Array is array (It.Unsigned_32 range 0 .. 1) of It.Unsigned_32; col : col_Array; IS_LIL_ENDIAN : boolean := BYTE_ORDER = LIL_ENDIAN; begin col (0) := It.Unsigned_32 (V.MapRGB (screen.format, 16#66#, 16#66#, 16#66#)); col (1) := It.Unsigned_32 (V.MapRGB (screen.format, 16#99#, 16#99#, 16#99#)); for y in It.Unsigned_32 range 0 .. It.Unsigned_32 (screen.h) - 1 loop for x in It.Unsigned_32 range 0 .. It.Unsigned_32 (screen.w) loop -- use an 8x8 checkboard pattern declare cl : It.Unsigned_32 := col (It.Shift_Right (x xor y, 3) and 1); begin case bpp is -- The following code is not very nice. Suggestions? when 1 => Uint8_PtrOps.Pointer ( Uint8_PtrOps.Pointer (Uint8_Ptrs.To_Pointer (dst)) + C.ptrdiff_t (x) ).all := Uint8 (cl); when 2 => Uint16_PtrOps.Pointer ( Uint16_PtrOps.Pointer (Uint16_Ptrs.To_Pointer (dst)) + C.ptrdiff_t (x) ).all := Uint16 (cl); when 3 => if IS_LIL_ENDIAN then Uint8_PtrOps.Pointer ( Uint8_PtrOps.Pointer (Uint8_Ptrs.To_Pointer (dst)) + C.ptrdiff_t (x * 3) ).all := Uint8 (cl); Uint8_PtrOps.Pointer ( Uint8_PtrOps.Pointer (Uint8_Ptrs.To_Pointer (dst)) + C.ptrdiff_t (x * 3 + 1) ).all := Uint8 (It.Shift_Right (cl, 8)); Uint8_PtrOps.Pointer ( Uint8_PtrOps.Pointer (Uint8_Ptrs.To_Pointer (dst)) + C.ptrdiff_t (x * 3 + 2) ).all := Uint8 (It.Shift_Right (cl, 16)); else Uint8_PtrOps.Pointer ( Uint8_PtrOps.Pointer (Uint8_Ptrs.To_Pointer (dst)) + C.ptrdiff_t (x * 3) ).all := Uint8 (It.Shift_Right (cl, 16)); Uint8_PtrOps.Pointer ( Uint8_PtrOps.Pointer (Uint8_Ptrs.To_Pointer (dst)) + C.ptrdiff_t (x * 3 + 1) ).all := Uint8 (It.Shift_Right (cl, 8)); Uint8_PtrOps.Pointer ( Uint8_PtrOps.Pointer (Uint8_Ptrs.To_Pointer (dst)) + C.ptrdiff_t (x * 3 + 2) ).all := Uint8 (cl); end if; when 4 => Uint32_PtrOps.Pointer ( Uint32_PtrOps.Pointer (Uint32_Ptrs.To_Pointer (dst)) + C.ptrdiff_t (x) ).all := Uint32 (cl); when others => null; end case; end; dst := Uint8_Ptrs.To_Address (Uint8_Ptrs.Object_Pointer ( Uint8_PtrOps.Pointer (Uint8_Ptrs.To_Pointer (dst)) + C.ptrdiff_t (screen.pitch))); end loop; end loop; end draw_background; -- ====================================== screen, image : V.Surface_ptr; depth : C.int; begin -- Check command line usage if CL.Argument_Count = 0 then Put_Line ("Usage: " & CL.Command_Name & " "); GNAT.OS_Lib.OS_Exit (1); end if; -- Initialize the SDL library if SDL.Init (SDL.INIT_VIDEO) < 0 then Put_Line ("Couldn't initialize SDL: " & IMG.Get_Error); GNAT.OS_Lib.OS_Exit (255); end if; -- Open the image file image := IMG.Load (CL.Argument (1)); if image = null then Put_Line ("Couldn't load " & CL.Argument (1)& ": " & IMG.Get_Error); SDL.SDL_Quit; GNAT.OS_Lib.OS_Exit (2); end if; V.WM_Set_Caption (CL.Argument (1), "showimage"); -- Create a display for the image depth := V.VideoModeOK (image.w, image.h, 32, V.SWSURFACE); -- Use the deepest native mode, except that we emulate 32bpp for -- viewing non-indexed images on 8bpp screens if image.format.BytesPerPixel > 1 and depth = 8 then depth := 32; end if; screen := V.SetVideoMode (image.w, image.h, depth, V.SWSURFACE); if screen = null then Put_Line ("Couldn't set " & C.int'Image (image.w) & "x" & C.int'Image (image.h) & "x" & C.int'Image (depth) & " video mode: " & IMG.Get_Error); SDL.SDL_Quit; GNAT.OS_Lib.OS_Exit (3); end if; -- set the palette, if one exists if image.format.palette /= null then V.SetColors (screen, image.format.palette.colors, 0, image.format.palette.ncolors); end if; -- Draw a background pattern if the surface has transparency if (image.flags and (V.SRCALPHA or V.SRCCOLORKEY)) /= 0 then null; end if; -- Display the image V.BlitSurface (image, null, screen, null); V.UpdateRect (screen, 0, 0, 0, 0); -- Wait for any keyboard or mouse input for i in Ev.NOEVENT .. Ev.NUMEVENTS - 1 loop case i is when Ev.KEYDOWN | Ev.MOUSEBUTTONDOWN | Ev.QUIT => -- Valid event, keep it null; when others => -- We don't want this event Ev.EventState (Ev.Event_Type (i), Ev.IGNORE); end case; end loop; Ev.WaitEvent (null); -- We're done! V.FreeSurface (image); SDL.SDL_Quit; GNAT.OS_Lib.OS_Exit (0); end ShowImage;