-- ----------------------------------------------------------------- -- -- -- -- This 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 software 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 library; if not, write to the -- -- Free Software Foundation, Inc., 59 Temple Place - Suite 330, -- -- Boston, MA 02111-1307, USA. -- -- -- -- ----------------------------------------------------------------- -- -- ----------------------------------------------------------------- -- -- This is a translation, to the Ada programming language, of the -- -- original C test files written by Sam Lantinga - www.libsdl.org -- -- translation made by Antonio F. Vargas - www.adapower.net/~avargas -- -- ----------------------------------------------------------------- -- -- ----------------------------------------------------------------- -- -- WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING -- ----------------------------------------------------------------- -- -- SERIOUS WARNING: The Ada code in this files may, at some points, -- rely directly on pointer arithmetic which is considered very -- unsafe and PRONE TO ERROR. The AdaSDL_Framebuffer examples are -- more appropriate and easier to understand. They should be used in -- replacement of this files. Please go there. -- This file exists only for the sake of completness and to test -- AdaSDL without the dependency of AdaSDL_Framebuffer. -- ----------------------------------------------------------------- -- -- WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING -- ----------------------------------------------------------------- -- with Interfaces.C; with Interfaces.C.Strings; with Lib_C; with Ada.Text_IO; use Ada.Text_IO; with Ada.Command_Line; with Ada.Characters.Handling; with GNAT.OS_Lib; with SDL.Video; with SDL.Error; with SDL.Types; use SDL.Types; with SDL.Timer; with SDL.Quit; procedure TestWin is package C renames Interfaces.C; use type C.int; use type C.size_t; package CS renames Interfaces.C.Strings; package CL renames Ada.Command_Line; package CH renames Ada.Characters.Handling; package V renames SDL.Video; use type V.Surface_ptr; use type V.Surface_Flags; use type V.Palette_ptr; package Er renames SDL.Error; package Tm renames SDL.Timer; type Colors_Array_Ptr is access V.Colors_Array; -- ====================================== procedure DrawPict (screen : V.Surface_ptr; bmpfile_name :CS.chars_ptr; speedy : C.int; flip : C.int; nofade : C.int) is package It renames Interfaces; use type It.Unsigned_32; use type CS.chars_ptr; use V.Color_PtrOps; bmpfile : CS.chars_ptr := bmpfile_name; picture : V.Surface_ptr; dest : V.Rect; update : V.Rect; centered : C.int; i : C.size_t; ncolors : C.int; -- cmap, colors : V.Color_ptr; cmap, colors : Colors_Array_Ptr; begin -- Load the image into a surface if bmpfile = CS.Null_Ptr then bmpfile := CS.New_String ("sample.bmp"); -- Sample image end if; Put_Line ("Loading picture: " & CS.Value (bmpfile)); picture := V.LoadBMP (bmpfile); if picture = null then Put_Line ("Couldn't load " & CS.Value (bmpfile) & ": " & Er.Get_Error); return; end if; -- Set the display colors -- on a hicolor display this is a no-op if picture.format.palette /= null then ncolors := picture.format.palette.ncolors; colors := new V.Colors_Array (0 .. C.size_t (ncolors) - 1); cmap := new V.Colors_Array (0 .. C.size_t (ncolors) - 1); colors.all := Value (Pointer (picture.format.palette.colors), C.ptrdiff_t (ncolors)); else -- Allocate 256 color palette ncolors := 256; colors := new V.Colors_Array (0 .. C.size_t (ncolors) - 1); cmap := new V.Colors_Array (0 .. C.size_t (ncolors) - 1); -- Set a 3,3,2 color cube for r in Uint8 range 0 .. 7 loop for g in Uint8 range 0 .. 7 loop for b in Uint8 range 0 .. 3 loop i := C.size_t (Shift_Left (r, 5) or Shift_Left (g, 2) or b); colors (i).r := Shift_Left (r, 5); colors (i).g := Shift_Left (g, 5); colors (i).b := Shift_Left (b, 6); end loop; end loop; end loop; end if; Put_Line ("testwin: setting colors"); declare Result : C.int; begin Result := V.SetColors (screen, colors.all, 0, ncolors); if Result = 0 and screen.format.palette /= null then Put_Line ("Warning: Couldn't set all of the colors, but SDL will " & "map the image"); Put_Line ("(colormap fading will suffer - try the -warp option)"); end if; end; -- Set the screen to black (not really necessary) if V.LockSurface (screen) = 0 then declare black : Uint32; pixels : Uint8_PtrOps.Pointer; use Uint8_Ptrs; use Uint8_PtrOps; begin black := V.MapRGB (screen.format, 0, 0, 0); pixels := Uint8_PtrOps.Pointer (To_Pointer (screen.pixels)); for i in 0 .. screen.h - 1 loop Lib_C.Mem_Set (To_Address (Object_Pointer (pixels)), C.int (black), C.size_t (screen.w) * C.size_t (screen.format.BytesPerPixel)); pixels := pixels + C.ptrdiff_t (screen.pitch); end loop; V.UnlockSurface (screen); V.UpdateRect (screen, 0, 0, 0, 0); end; end if; -- Display the picture if speedy /= 0 then declare displayfmt : V.Surface_ptr; begin Put_Line ("Converting picture"); displayfmt := V.DisplayFormat (picture); if displayfmt = null then Put_Line ("couldn't convert image: " & Er.Get_Error); goto done; end if; V.FreeSurface (picture); picture := displayfmt; end; end if; Put ("(image surface located in "); if (picture.flags and V.HWSURFACE) /= 0 then Put ("video"); else Put ("system"); end if; Put_Line (" memory"); centered := (screen.w - picture.w) / 2; if centered < 0 then centered := 0; end if; dest.y := Sint16 ((screen.h - picture.h) / 2); dest.w := Uint16 (picture.w); dest.h := Uint16 (picture.h); Put_Line ("testwin: moving image"); for i in 0 .. centered - 1 loop dest.x := Sint16 (i); update := dest; if V.BlitSurface (picture, null, screen, update) < 0 then Put_Line ("Blit failed: " & Er.Get_Error); end if; if flip /= 0 then V.Flip (screen); else V.Update_Rect (screen, update); end if; end loop; -- #ifdef SCREENSHOT if V.SaveBMP (screen, CS.New_String ("screen.bmp")) < 0 then Put_Line ("Couldn't save screen: " & Er.Get_Error); end if; -- #endif -- #ifndef BENCHMARK_SDL -- Let it sit there for a while -- Tm.SDL_Delay (5 * 1000); -- #endif -- Fade the colormap if nofade = 0 then declare maxstep : C.int; final : V.Color; palcolors : Colors_Array_Ptr := new V.Colors_Array (0 .. C.size_t (ncolors) - 1); type cdist_Rec is record r, g, b : Sint16; end record; type cdist_Array is array (C.size_t range <>) of cdist_Rec; type cdist_Array_ptr is access cdist_Array; cdist : cdist_Array_ptr := new cdist_Array (0 .. C.size_t (ncolors) - 1); begin Put_Line ("testwin: fading out ..."); cmap.all := colors.all; maxstep := 32 - 1; final.r := 16#FF#; final.g := 16#00#; final.b := 16#00#; palcolors.all := colors.all; for i in cdist'Range loop cdist (i).r := Sint16 (final.r - palcolors (i).r); cdist (i).g := Sint16 (final.g - palcolors (i).g); cdist (i).b := Sint16 (final.b - palcolors (i).b); end loop; for i in 0 .. maxstep / 2 loop -- halfway fade for count in C.size_t range 0 .. C.size_t (ncolors) - 1 loop colors (count).r := Uint8 ( Sint16 (palcolors (count).r) + (cdist (count).r * Sint16 (i)) / Sint16 (maxstep)); colors (count).g := Uint8 ( Sint16 (palcolors (count).g) + (cdist (count).g * Sint16 (i)) / Sint16 (maxstep)); colors (count).b := Uint8 ( Sint16 (palcolors (count).r) + (cdist (count).b * Sint16 (i)) / Sint16 (maxstep)); end loop; V.SetColors (screen, colors.all, 0, ncolors); Tm.SDL_Delay (1); end loop; final.r := 16#00#; final.g := 16#00#; final.b := 16#00#; palcolors.all := colors.all; for i in cdist'Range loop cdist (i).r := Sint16 (final.r - palcolors (i).r); cdist (i).g := Sint16 (final.g - palcolors (i).g); cdist (i).b := Sint16 (final.b - palcolors (i).b); end loop; maxstep := maxstep / 2; for i in 0 .. maxstep - 1 loop -- finish fade out for count in C.size_t range 0 .. C.size_t (ncolors) - 1 loop colors (count).r := Uint8 ( Sint16 (palcolors (count).r) + (cdist (count).r * Sint16 (i)) / Sint16 (maxstep)); colors (count).g := Uint8 ( Sint16 (palcolors (count).g) + (cdist (count).g * Sint16 (i)) / Sint16 (maxstep)); colors (count).b := Uint8 ( Sint16 (palcolors (count).r) + (cdist (count).b * Sint16 (i)) / Sint16 (maxstep)); end loop; V.SetColors (screen, colors.all, 0, ncolors); Tm.SDL_Delay (1); end loop; for i in colors'Range loop colors (i).r := final.r; colors (i).g := final.g; colors (i).b := final.b; end loop; V.SetColors (screen, colors.all, 0, ncolors); Put_Line ("testwin: fading in .."); palcolors.all := colors.all; for i in cdist'Range loop cdist (i).r := Sint16 (final.r - palcolors (i).r); cdist (i).g := Sint16 (final.g - palcolors (i).g); cdist (i).b := Sint16 (final.b - palcolors (i).b); end loop; for i in 0 .. maxstep - 1 loop -- 32 step fade for count in C.size_t range 0 .. C.size_t (ncolors) - 1 loop colors (count).r := Uint8 ( Sint16 (palcolors (count).r) + (cdist (count).r * Sint16 (i)) / Sint16 (maxstep)); colors (count).g := Uint8 ( Sint16 (palcolors (count).g) + (cdist (count).g * Sint16 (i)) / Sint16 (maxstep)); colors (count).b := Uint8 ( Sint16 (palcolors (count).r) + (cdist (count).b * Sint16 (i)) / Sint16 (maxstep)); end loop; V.SetColors (screen, colors.all, 0, ncolors); Tm.SDL_Delay (1); end loop; Put_Line ("testing: fading over"); end; -- declare end if; -- nofade = 0 <> -- Free the picture and return V.FreeSurface (picture); end DrawPict; -- ====================================== package int_IO is new Ada.Text_IO.Integer_IO (C.int); use int_IO; screen : V.Surface_ptr; -- Options speedy, flip, nofade : C.int; the_delay : C.int; w, h : C.int; desired_bpp : C.int; video_flags : V.Surface_Flags; -- #ifdef BENCHMARK_SDL and_then, now : Uint32; -- #endif; argc : Integer := CL.Argument_Count; argv_i : Integer := 1; bmpfile_name : CS.chars_ptr := CS.Null_Ptr; begin -- Set default option and check command-line speedy := 0; flip := 0; nofade := 0; the_delay := 1; w := 640; h := 480; desired_bpp := 0; video_flags := 0; while argc > 0 loop if CL.Argument (argv_i) = "-speedy" then speedy := 1; argv_i := argv_i + 1; argc := argc - 1; elsif CL.Argument (argv_i) = "-nofade" then nofade := 1; argv_i := argv_i + 1; argc := argc - 1; elsif (argc > 1) and then (CL.Argument (argv_i) = "-delay") then if CH.Is_Digit (CL.Argument (argv_i + 1) (1)) then declare last : Positive; begin Get (CL.Argument (argc), the_delay, last); end; argv_i := argv_i + 2; argc := argc - 2; else Put_Line ("The -delay requires a numeric argument"); GNAT.OS_Lib.OS_Exit (1); end if; elsif (argc > 1) and then (CL.Argument (argv_i) = "-width") then if CH.Is_Digit (CL.Argument (argv_i + 1) (1)) then declare last : Positive; begin Get (CL.Argument (argc), w, last); end; argv_i := argv_i + 2; argc := argc - 2; else Put_Line ("The -width requires a numeric argument"); GNAT.OS_Lib.OS_Exit (1); end if; elsif (argc > 1) and then (CL.Argument (argv_i) = "-height") then if CH.Is_Digit (CL.Argument (argv_i + 1) (1)) then declare last : Positive; begin Get (CL.Argument (argc), h, last); end; argv_i := argv_i + 2; argc := argc - 2; else Put_Line ("The -height requires a numeric argument"); GNAT.OS_Lib.OS_Exit (1); end if; elsif (argc > 1) and then (CL.Argument (argv_i) = "-bpp") then if CH.Is_Digit (CL.Argument (argv_i + 1) (1)) then declare last : Positive; begin Get (CL.Argument (argc), desired_bpp, last); end; argv_i := argv_i + 2; argc := argc - 2; else Put_Line ("The -bpp requires a numeric argument"); GNAT.OS_Lib.OS_Exit (1); end if; elsif CL.Argument (argv_i) = "-warp" then video_flags := video_flags or V.HWPALETTE; argv_i := argv_i + 1; argc := argc -1; elsif CL.Argument (argv_i) = "-hw" then video_flags := video_flags or V.HWSURFACE; argv_i := argv_i + 1; argc := argc - 1; elsif CL.Argument (argv_i) = "-flip" then video_flags := video_flags or V.DOUBLEBUF; argv_i := argv_i + 1; argc := argc - 1; elsif CL.Argument (argv_i) = "-fullscreen" then video_flags := video_flags or V.FULLSCREEN; argv_i := argv_i + 1; argc := argc - 1; elsif CL.Argument (argv_i) = "-help" then Put_Line ("Usage: " & CL.Command_Name & " " & "[-speedy] [-nofade] [-delay N] [-width N] [-height -N] " & "[-bpp N] [-warp] [-hw] [-flip] [-fullscreen] [-help]"); GNAT.OS_Lib.OS_Exit (1); else bmpfile_name := CS.New_String (CL.Argument (argv_i)); argv_i := argv_i + 1; argc := argc - 1; end if; end loop; if SDL.Init (SDL.INIT_VIDEO) < 0 then Put_Line ("Couldn't initialize SDL: " & Er.Get_Error); GNAT.OS_Lib.OS_Exit (1); end if; -- Set video mode screen := V.SetVideoMode (w, h, C.int (desired_bpp), video_flags); if screen = null then Put_Line ("Couldn't set " & C.int'Image (w) & "x" & C.int'Image (h) & " video mode: " & Er.Get_Error); GNAT.OS_Lib.OS_Exit (1); end if; Put_Line ("Set " & C.int'Image (screen.w) & "x" & C.int'Image (screen.h) & "x" & Uint8'Image (screen.format.BitsPerPixel) & " mode"); Put ("(video surface located in "); if (screen.flags and V.HWSURFACE) /= 0 then Put ("video"); else Put ("system"); end if; Put_Line (" memory"); if (screen.flags and V.DOUBLEBUF) /= 0 then Put_Line ("Double-buffering enabled"); flip := 1; end if; -- Set the window manager title bar V.WM_SetCaption (CS.New_String ("SDL test window"), CS.New_String ("testwin")); SDL.Quit.atexit (SDL.SDL_Quit'Access); -- Clean up on exit -- Do all the drawing work -- #ifdef BENCHMARK_SDL and_then := Tm.GetTicks; DrawPict (screen, bmpfile_name, speedy, flip, nofade); now := Tm.GetTicks; Put_Line ("Time: " & Uint32'Image (now - and_then) & " milliseconds"); -- #else -- DrawPict (screen, bmpfile_name, speedy, flip, nofade); -- #endif Tm.SDL_Delay (Uint32 (the_delay * 1000)); GNAT.OS_Lib.OS_Exit (0); end TestWin;