comp.lang.ada
 help / color / mirror / Atom feed
From: "Nick Roberts" <nickroberts@callnetuk.com>
Subject: Re: More C
Date: 2000/01/30
Date: 2000-01-30T00:00:00+00:00	[thread overview]
Message-ID: <3896134b@eeyore.callnetuk.com> (raw)
In-Reply-To: vhizotrc4x7.fsf@grotte.ifi.uio.no

With the greatest respect, I think this a classic case of C programmer
trying to make Ada do things the way they have to be done in C.

In Ada, you are able to specify the representation of types, and you also
have recourse to the standard Interfaces.C package (and its children) for
interfacing to C functions and objects. This means that, in Ada, you can
often specify types that correspond more closely to the high-level meaning
of a type, and let representation clauses, as well as type derivation
techniques, take care of the nitty gritty details of how they should be
represented in the machine.

   type Light_Level_8 is range 0..255;
   for Light_Level_8'Size use 8;

   type SDL_Color is
      record
         Red, Green, Blue: Light_Level_8;
      end record;

   for SDL_Color use
      record
         Red at 0 range 0..7;
         Green at 0 range 8..15;
         Red at 0 range 16.23;
      end record;

   for SDL_Color'Size use 32;

   type SDL_Color_Array is array (Integer) of aliased SDL_Color;

   SDLCT: SDL_Color := (0,0,0); -- default 'terminator' of arrays
   -- provided because Interfaces.C.Pointers needs it, but unlikely to be
used

   package SDL_Color_Pointers is
      new Interfaces.C.Pointers(Integer,SDL_Color,SDL_Color_Array,SDLCT);

   subtype Color_Count is Interfaces.C.Int range 0..Interfaces.C.Int'Last;

   type SDL_Palette is
      record
         Number_Of_Colors: Color_Count;
         Colors: SDL_Color_Pointers.Pointer;
      end record;

   Int_Size: constant := Interfaces.C.Int'Size;

   for SDL_Palette use
      record
         Number_of_Colors at 0 range 0..Int_Size-1;
         Colors at 0 range
Int_Size..Int_Size+SDL_Color_Pointers.Pointer'Size-1;
      end record;

You can use the Value function (and others) of the SDL_Color_Pointers
package to access, easily and efficiently, the contents of arrays pointed to
by the Colors component.

Ada offers a particularly better way of accessing your display buffer.

   type Light_Level_2 is range 0..3;
   for Light_Level_2'Size use 2;

   type Light_Level_3 is range 0..7;
   for Light_Level_3'Size use 3;

   type Color_Descriptor_8 is
      record
         Red, Green: Light_Level_3;
         Blue: Light_Level_2;
      end record;

   for Color_Desriptor_8 use
      record
         Red: at 0 range 0..2;
         Green: at 0 range 3..5;
         Blue: at 0 range 6..7;
      end record;

   -- and so on for Color_Descriptor_16 and Color_Descriptor_32

   type Display_Buffer_8 is array (Integer, Integer) of aliased
Color_Descriptor_8;
   type Display_Buffer_16 is array (Integer, Integer) of aliased
Color_Descriptor_16;
   type Display_Buffer_32 is array (Integer, Integer) of aliased
Color_Descriptor_32;

   pragma Convention(Fortran,Display_Buffer_8);
   pragma Convention(Fortran,Display_Buffer_16);
   pragma Convention(Fortran,Display_Buffer_32);
   -- for (X,Y) ensure X dimension varies faster than Y

   package Display_Buffer_8_Pointers is
      new
Interfaces.C.Pointers(Integer,Color_Descriptor_8,Display_Buffer_8,...);
   -- etc

   subtype CGA_Buffer is Display_Buffer_8(1..320,1..200);
   for CGA_Buffer'Size use 320*200*8;
   pragma Volatile(CGA_Buffer); -- tell Ada it's memory mapped

   type CGA_Buffer_Access is access all CGA_Buffer;

You might import 'data', using the Import pragma, use Unchecked_Conversion
to typecast it as a Display_Buffer_8/16/32_Pointers.Pointer, and then
convert from Display_Buffer_8/16/32_Pointers.Pointer to CGA_Buffer_Access
(for example). Now you can read from and write into the buffer just like you
would a normal two-dimensional Ada array. You can't really get much more
convenient than that.

NB: the two-dimensional array addressing should be optimised adequately by
most Ada compilers, but if not, and you need the extra speed, you can use
the Value function (and others) to access the contents of the display
buffers instead. In cases such as this, try to 'wrap up' higher level
operations into procedures and functions; the Inline pragma can be used to
prevent this technique from reducing speed.

Best of luck!

--
Nick Roberts
http://www.adapower.com/lab/adaos







  parent reply	other threads:[~2000-01-30  0:00 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <vhizotrc4x7.fsf@grotte.ifi.uio.no>
2000-01-28  0:00 ` More C Jeff Carter
2000-01-28  0:00 ` Gautier
2000-01-28  0:00 ` tmoran
2000-01-28  0:00   ` David Starner
2000-01-28  0:00     ` Pascal Obry
2000-01-28  0:00       ` David Starner
2000-01-28  0:00         ` tmoran
2000-01-30  0:00 ` Nick Roberts [this message]
     [not found]   ` <vhioga1r2j8.fsf@grotte.ifi.uio.no>
2000-02-01  0:00     ` tmoran
2000-02-02  0:00     ` Nick Roberts
2000-02-03  0:00     ` Keith Thompson
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox