* Re: More C [not found] <vhizotrc4x7.fsf@grotte.ifi.uio.no> @ 2000-01-28 0:00 ` tmoran 2000-01-28 0:00 ` David Starner 2000-01-28 0:00 ` Gautier ` (2 subsequent siblings) 3 siblings, 1 reply; 11+ messages in thread From: tmoran @ 2000-01-28 0:00 UTC (permalink / raw) type SDL_Color is record R, G, B: C.Unsigned_Char; end record; for SDL_Color'size use 4*8; for SDL_Color use record R at 0 range 0 .. 7; G at 1 range 0 .. 7; B at 2 range 0 .. 7; end record; -- You might want to replace C.Unsigned_Char with something like -- type Intensity is range 0 .. 255; -- for Intensity'size use 8; type SDL_Color_Access is access SDL_Color; type Color_List is array(C.Int range <>) of aliased SDL_Color; type Color_List_Access is access all Color_List; type SDL_Palette is record Number_Of_Colors: C.Int; Colors: Color_List_Access; end record; I presume you really want Colors to point to a Color_List, not to a single color. Note that Colors will point to a list of N colors, where N may, or may not, equal Number_Of_Colors. So you can either ignore Number_Of_Colors (using Palette.Colors.all'length if you need the count of colors in the list) or you can have your "Indexed" function do a check that "Index in 1 .. Number_Of_Colors" or "Index in 0 .. Number_Of_Colors-1" or whatever, in addition to the automatic index check. function Indexed_Color_Access(Palette: SDL_Palette; Index: C.Int) return SDL_Color_Access is begin if Index in 1 .. Palette.Number_Of_Colors then return Palette.Colors(Index)'access; else raise Constraint_Error; end if; end Indexed_Color_Access; Depending on what you're doing, you might want: function Indexed_Color(Palette: SDL_Palette; Index: C.Int) return SDL_Color is begin if Index in 1 .. Palette.Number_Of_Colors then return Palette.Colors(Index); else raise Constraint_Error; end if; end Indexed_Color; In both of the above functions, if you really want to have type SDL_Palette_Access is access SDL_Palette; and have the functions take a parameter of Palette : SDL_Palette_Access; instead of Palette : SDL_Palette; then the rest of the function still works as written because Palette.Number_Of_Colors and Palette.Colors(Index) are equivalent to (Palette.all).Number_Of_Colors and (Palette.all).Colors(Index) Note that I've changed Color_Array to Palette, since an SDL Palette is more than just an array. If the structure of SDL_Palette as a count and a pointer isn't forced on you, of course, it would be simpler to just use the Color_List array (perhaps renaming Color_List to Palette). Then just refer to Color_Array(Index) where, e.g., Color_Array : Color_List(1 .. 17); If you really must match the memory layout of the C SDL_Palette, type Arbitrary_Color_List is array(C.Int range) of aliased SDL_Color; type Arbitrary_Color_List_Access is access all Color_List; type SDL_Palette is record Number_Of_Colors: C.Int; Colors: Arbitrary_Color_List_Access; end record; is probably your best bet. You then have to do your own index checking, just as in C, and you'll want a representation clause. It's possible in Ada to do dangerous things like address arithmetic to look at storage a certain number of bytes beyond where a particular SDL_Color is stored, but it should rarely be needed. If it is really needed, look at packages System.Storage_Elements and System.Address_To_Access_Conversions For some examples of records laid out to communicate with Windows about colors and bitmaps, see Claw (internal package Colors) and Claw.Bitmaps in the $0 version of Claw at www.rrsoftware.com ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: More C 2000-01-28 0:00 ` More C tmoran @ 2000-01-28 0:00 ` David Starner 2000-01-28 0:00 ` Pascal Obry 0 siblings, 1 reply; 11+ messages in thread From: David Starner @ 2000-01-28 0:00 UTC (permalink / raw) On Fri, 28 Jan 2000 05:14:39 GMT, tmoran@bix.com <tmoran@bix.com> wrote: >type SDL_Palette is record > Number_Of_Colors: C.Int; > Colors: Color_List_Access; >end record; > >I presume you really want Colors to point to a Color_List, not to a >single color. Note that Colors will point to a list of N colors, >where N may, or may not, equal Number_Of_Colors. So you can either >ignore Number_Of_Colors (using Palette.Colors.all'length if you need >the count of colors in the list) or you can have your "Indexed" >function do a check that "Index in 1 .. Number_Of_Colors" or >"Index in 0 .. Number_Of_Colors-1" or whatever, in addition to the >automatic index check. This seems wrong. What gives Ada the information about how long that list is? Looking at the C structure, the reason why Number_Of_Colors was stored there is so that the length is known, and it is not stored anywhere else. -- David Starner - dstarner98@aasaa.ofe.org If you wish to strive for peace of soul then believe; if you wish to be a devotee of truth, then inquire. -- Friedrich Nietzsche ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: More C 2000-01-28 0:00 ` David Starner @ 2000-01-28 0:00 ` Pascal Obry 2000-01-28 0:00 ` David Starner 0 siblings, 1 reply; 11+ messages in thread From: Pascal Obry @ 2000-01-28 0:00 UTC (permalink / raw) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 1076 bytes --] David, The answer to your question was in the message you quoted! To know the number of colors use : Palette.Colors'Length (.all is not required here I think). You can also iterate through the table using: for K in Palette.Colors'Range loop ... end loop; Did I missed something ? Pascal. -- --|------------------------------------------------------------ --| Pascal Obry Team-Ada Member | --| | --| EDF-DER-IPN-SID- T T I | --| Intranet: http://cln46gb | --| Bureau N-023 e-mail: p.obry@der.edf.fr | --| 1 Av G�n�ral de Gaulle voice : +33-1-47.65.50.91 | --| 92141 Clamart CEDEX fax : +33-1-47.65.50.07 | --| FRANCE | --|------------------------------------------------------------ --| --| http://perso.wanadoo.fr/pascal.obry --| --| "The best way to travel is by means of imagination" ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: More C 2000-01-28 0:00 ` Pascal Obry @ 2000-01-28 0:00 ` David Starner 2000-01-28 0:00 ` tmoran 0 siblings, 1 reply; 11+ messages in thread From: David Starner @ 2000-01-28 0:00 UTC (permalink / raw) On Fri, 28 Jan 2000 09:36:15 +0100, Pascal Obry <p.obry@der.edf.fr> wrote: >David, > >The answer to your question was in the message you quoted! > >To know the number of colors use : Palette.Colors'Length (.all is >not required here I think). > >You can also iterate through the table using: > > for K in Palette.Colors'Range loop > ... > end loop; > >Did I missed something ? We have a similar structure struct bob { char num_chars_in_b; char *b; /* array */ }; In memory (assuming 8 bit pointers) we have num_chars_in_b | pointer array | | | 03 20 ...... 01 10 10 23 58 20 48 . . . The only place in that memory where it tells you the length of the array is num_chars_in_b. No matter how you translate that structure into Ada, Ada can't give you the length of the array independent of num_chars_in_b, because it doesn't have the information. Or so I understand it. -- David Starner - dstarner98@aasaa.ofe.org If you wish to strive for peace of soul then believe; if you wish to be a devotee of truth, then inquire. -- Friedrich Nietzsche ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: More C 2000-01-28 0:00 ` David Starner @ 2000-01-28 0:00 ` tmoran 0 siblings, 0 replies; 11+ messages in thread From: tmoran @ 2000-01-28 0:00 UTC (permalink / raw) >In memory (assuming 8 bit pointers) we have > >num_chars_in_b >| pointer array >| | | >03 20 ...... 01 10 10 23 58 20 48 . . . > >The only place in that memory where it tells you the length of the >array is num_chars_in_b. No matter how you translate that structure >into Ada, Ada can't give you the length of the array independent of >num_chars_in_b, because it doesn't have the information. Or so >I understand it. Quite so. But in the message I posted it said: >I presume you really want Colors to point to a Color_List, not to a >single color. Note that Colors will point to a list of N colors, >where N may, or may not, equal Number_Of_Colors. in which case the pointer points to an array and the compiler either knows its bounds or knows where to look to find its bounds (if they are dynamic). The case you have is: >If you really must match the memory layout of the C SDL_Palette, > >type Arbitrary_Color_List is array(C.Int range) of aliased SDL_Color; >type Arbitrary_Color_List_Access is access all Color_List; > >type SDL_Palette is record > Number_Of_Colors: C.Int; > Colors: Arbitrary_Color_List_Access; >end record; > >is probably your best bet. You then have to do your own index >checking, just as in C, and you'll want a representation clause. Since the compiler knows the (unchanging) bounds, here all of C.Int, it needn't put them in memory anywhere and can set the pointer to the array Colors to be the identical bits to a pointer to the first element of Colors, which matches the C layout. There's no guarantee it will do this, so you must experiment to see what happens and put big signs around warning of danger, but it will probably work. An alternative, more work but likely more safely portable, is the suggestion from Jeff Carter of >type SDL_Palette is record > Num_Colors : C.Int; > Address_Of_Color_Array : System.Address; >end record; > >Given: > > Palette : SDL_Palette; > >containing data from C, use > >type Color_Set is array (C.Int range <>) of SDL_Color; > >Colors : Color_Set (1 .. Palette.Num_Colors); >for Colors'Address use Palette.Address_Of_Color_Array; Note, however, that a C pointer is not necessarily the same as an Ada System.Address (consider various i86 memory models) so that probably ought to be modified to type SDL_Palette is record Num_Colors : C.Int; C_Access_Of_Color_Array : Interfaces.C.Strings.char_array_access; end record; and then use System.Address_To_Access_Conversions to convert C_Access_Of_Color_Array to a System.Address to use in the for Colors'Address use the_address_from_C_Access_Of_Color_Array; PS. I should have said type Arbitrary_Color_List is array(C.Int range 0 .. C.Int'last) of aliased SDL_Color; since you probably want index 0 (or maybe 1), rather than C.Int'first, to indicate the first element. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: More C [not found] <vhizotrc4x7.fsf@grotte.ifi.uio.no> 2000-01-28 0:00 ` More C tmoran @ 2000-01-28 0:00 ` Gautier 2000-01-28 0:00 ` Jeff Carter 2000-01-30 0:00 ` Nick Roberts 3 siblings, 0 replies; 11+ messages in thread From: Gautier @ 2000-01-28 0:00 UTC (permalink / raw) If it can help (e.g. for your buffer questions, you can take a look at code in svga02x4.zip, link below). -- Gautier _____\\________________\_______\_________ http://members.xoom.com/gdemont/gsoft.htm ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: More C [not found] <vhizotrc4x7.fsf@grotte.ifi.uio.no> 2000-01-28 0:00 ` More C tmoran 2000-01-28 0:00 ` Gautier @ 2000-01-28 0:00 ` Jeff Carter 2000-01-30 0:00 ` Nick Roberts 3 siblings, 0 replies; 11+ messages in thread From: Jeff Carter @ 2000-01-28 0:00 UTC (permalink / raw) Jan Kroken wrote: > I have the following C structs > > typedef struct { > Uint8 r; > Uint8 g; > Uint8 b; > Uint8 unused; > } SDL_Color; > > typedef struct { > int ncolors; /* number of colors */ > SDL_Color *colors; /* array of colors */ > } SDL_Palette; > > and have included them in Ada as > > type SDL_Color is record > R, G, B, Unused: C.Unsigned_Char; > end record; Note the comment that this is an array. The best way to treat this in Ada is probably as an array: type SDL_Palette is record Num_Colors : C.Int; Address_Of_Color_Array : System.Address; end record; Given: Palette : SDL_Palette; containing data from C, use type Color_Set is array (C.Int range <>) of SDL_Color; Colors : Color_Set (1 .. Palette.Num_Colors); for Colors'Address use Palette.Address_Of_Color_Array; That only answers 1 of your 2 questions, I'm afraid. -- Jeff Carter "We burst our pimples at you." Monty Python & the Holy Grail ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: More C [not found] <vhizotrc4x7.fsf@grotte.ifi.uio.no> ` (2 preceding siblings ...) 2000-01-28 0:00 ` Jeff Carter @ 2000-01-30 0:00 ` Nick Roberts [not found] ` <vhioga1r2j8.fsf@grotte.ifi.uio.no> 3 siblings, 1 reply; 11+ messages in thread From: Nick Roberts @ 2000-01-30 0:00 UTC (permalink / raw) 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 ^ permalink raw reply [flat|nested] 11+ messages in thread
[parent not found: <vhioga1r2j8.fsf@grotte.ifi.uio.no>]
* Re: More C [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 2 siblings, 0 replies; 11+ messages in thread From: tmoran @ 2000-02-01 0:00 UTC (permalink / raw) >What if the compiler decides to optimize access to the record, >so the real memory structure becomes as follows? If you give a record representation clause it can't. Without the rep' clause, yes, and there are compilers that would optimize by putting things at double word boundaries or whatever. That's the whole reason for rep clauses - when the memory layout really, truly, has to be a certain way. >it's not going to replace the original one dimentional buffer, since >you then would have to know the dimentions, or at least a set of possible >dimentions, in advance. But you could as example read the dimentions >from the command line or from an image file. A long time ago I made a VESA graphic interface. At initialization it asked the hardware what resolution modes were available, found the best (criterion supplied by the application program), and defined subtype X_Range is Integer range 0 .. X_Res; subtype Y_Range is Integer range 0 .. Y_Res; which could then be used for Image : array(Y_Range, X_Range) of Pixels; It's certainly no less efficient to have the compiler generate code to multiply the Y coordinate by the row size and add the X coordinate, vs having the user do it explicitly and visibly. It may even be more efficient. It's also a lot less likely to have a mistake. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: More C [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 2 siblings, 0 replies; 11+ messages in thread From: Nick Roberts @ 2000-02-02 0:00 UTC (permalink / raw) Jan's comments broadly accepted. It surely demonstrates one aspect of the deficiencies of C as a software engineering language, that the programmer has, in general, no control over how types are represented, and that it is common for C compilers to vary from one another (and the ANSI standard) in this matter. In this respect, it is necessary to think of interfacing Ada source code not to C source code, but to C object code (i.e. C source as compiled by a particular version of a particular compiler, with a particular set of flags in force). To the rescue, to a certain extent, comes the ability of most C compilers to output an assembly listing (or other listing) that shows the representations (and addresses) chosen for types and objects. -- Nick Roberts http://www.adapower.com/lab/adaos "Jan Kroken" <jankr@nntp.ifi.uio.no> wrote in message news:vhioga1r2j8.fsf@grotte.ifi.uio.no... > ... > What if the [C] compiler decides to optimize access to the record, > so the real memory structure becomes as follows? > > for SDL_Color use > record > Red at 0 range 0..7; > Green at 32 range 32..39; > Blue at 64 range 64..71; > end record; > for SDL_Color'Size use 128; > ... ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: More C [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 2 siblings, 0 replies; 11+ messages in thread From: Keith Thompson @ 2000-02-03 0:00 UTC (permalink / raw) Jan Kroken <jankr@nntp.ifi.uio.no> writes: [...] > What if the compiler decides to optimize access to the record, > so the real memory structure becomes as follows? > > for SDL_Color use > record > Red at 0 range 0..7; > Green at 32 range 32..39; > Blue at 64 range 64..71; > end record; > for SDL_Color'Size use 128; You should be able to use pragma Convention(C, SDL_Color); it's then up to the Ada compiler to lay out the record the same way the C compiler does. If it doesn't do this properly, you may have to resort to record representation clauses, or perhaps to an implementation-defined pragma. -- Keith Thompson (The_Other_Keith) kst@cts.com <http://www.ghoti.net/~kst> San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst> Welcome to the last year of the 20th century. ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2000-02-03 0:00 UTC | newest] Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <vhizotrc4x7.fsf@grotte.ifi.uio.no> 2000-01-28 0:00 ` More C 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-28 0:00 ` Gautier 2000-01-28 0:00 ` Jeff Carter 2000-01-30 0:00 ` Nick Roberts [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
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox