PDA

View Full Version : Convert C to Pas



kordal
02-03-2013, 02:14 PM
Hi, everybody! I ask for help with transfer of part of a code with C ++ on Delphi. Partially I translated, but I doubt correctness. Files I attach.
In advance, Many thanks!

Super Vegeta
02-03-2013, 11:30 PM
Why does types.pas use longint/single etc., instead of GLtype? These are defined in FPC OGL units, too. May the same memory-wise, but, well, this kind of inconsistency bothers me.

User137
03-03-2013, 03:03 AM
_types.pas:
You don't need C-like weirdnesses with random(). We have a much more sophisticated function in our language 8)


// not 100% sure of this one. That -0.5 could make it rounded differently.
function RAND(X: Integer): Single;
begin
//Result := (Random(RAND_MAX) / RAND_MAX - 0.5) * X;
Result:=Random()*X;
end;


function RANDI(X: Integer): Integer;
begin
//Result := Round((Abs(Random(RAND_MAX) / RAND_MAX * X)));
Result := Random(X);
end;

I see you made int into integer. May depend on compiler, but generally i guess its safe to assume int = 2 bytes, meaning smallint or word.
http://en.wikipedia.org/wiki/C_data_types
However "int size" in that code can get values from 16 to 128, and other function does size*size*2, which would be 32768. That would overflow, because 32767 is largest allowed for signed. So i'd prolly go with using longint aswell on the size. I don't know how well that asm code manages with that then.

Also, compiling pascal program for 64-bit system would consider integer = int64, would it not? I don't have 64-bit system, and only guessing. Longint type is guaranteed 4 bytes.

phibermon
03-03-2013, 02:50 PM
short int = 16bit

long int = 32bit

int on it's own is supposed to be the platforms native integer as stored in a CPU register, so on a 64bit CPU running a 64bit OS, int = 64bit. On a 32bit Arm platform (like the Iphone) it's 32bits

Now if using a smaller size than native in ASM will break the code? well it depends on the operations you're carrying out, instructions/registers used etc the CPU can mix and perform operations on various combinations of integers of different sizes, no problem adding an 8bit number to a 64bit number and so on, it's the size of the register in which the CPU stores the result and the type of variable in memory in which the result is saved that matters, too small and it overflows. this is all handled in a compiler and warnings are given if you explicitly state the result to be stored in a smaller int (you may of seen compiler messages along the lines of 'mixing of two types gives 64bit result' etc) however even if you're storing a 16bit int, the actual operation might of took place in 32bit registers.

If you're using pointers for example they are the native int format, so would be 32 or 64bits depending on your CPU - OS - compiler. (and when I say 64bit OS, I mean an OS that puts the CPU into 64bit mode)

Anyway, all that said, you shouldn't be doing this graphics routine like this, it's woefully slow even if you use ASM (and just writing it in pascal will not result in code that's much slower) You should be using GLSL, judging by the techniques used in the C source, this was written before shaders existed, it's what you'd do if you didn't have a programmable pipeline. Plus this is x86 ASM, by using it you're not going to be porting to android/iphone unless you write equivlent ASM routines for ARM, or use the language and let the compiler do it.

Ñuño Martínez
09-03-2013, 06:20 PM
short int = 16bit

long int = 32bit

int on it's own is supposed to be the platforms native integer as stored in a CPU register, so on a 64bit CPU running a 64bit OS, int = 64bit. On a 32bit Arm platform (like the Iphone) it's 32bits

(...)

Yes, 32bit/64bit support is quite tricky. I build a Unit that seems to work for Allegro.pas (or it does for Linux and Allegro 4, but it doesn't seems to work so good with Allegro 5 or Win64 :(). Look at it:


(*
Next are definitions of numeric data types. We may use FPC's ctype unit,
but Delphi doesn't has it so I prefer to do it by hand.
First: it defines some integers with specific lenght.
Then: it defines the types used by C declarations.
*)
TYPE
(* Generic pointer. *)
AL_POINTER = POINTER;
(* Signed 8bit integer values. *)
AL_INT8 = SHORTINT;
(* Unsigned 8bit integer values. *)
AL_UINT8 = BYTE;
(* Signed 16bit integer values. *)
AL_INT16 = SMALLINT;
(* Unsigned 16bit integer values. *)
AL_UINT16 = WORD;
(* Signed 32bit integer values. *)
AL_INT32 = LONGINT;
(* Unsigned 32bit integer values. *)
AL_UINT32 = LONGWORD;
(* Signed 64bit integer values. *)
AL_INT64 = INT64;
(* Unsigned 64bit integer values. *)
AL_UINT64 = QWORD;
(* Signed 8bit integer.
Note that it isn't Pascal's CHAR type! *)
AL_CHAR = AL_INT8;
(* Unsigned 8bit integer values. *)
AL_UCHAR = AL_UINT8;
(* Signed 16bit integer values. *)
AL_SHORT = AL_INT16;
(* Unsigned 16bit integer values. *)
AL_USHORT = AL_UINT16;
(* Signed 32bit integer values. *)
AL_INT = AL_INT32;
(* Unsigned 32bit integer values. *)
AL_UINT = AL_UINT32;
{$IFDEF CPU64}
{$IFDEF WINDOWS}
(* Signed 32/64bit integer values. *)
AL_LONG = AL_INT32;
(* Unsigned 32/64bit integer values. *)
AL_ULONG = AL_UINT32;
{$ELSE}
(* Signed 32/64bit integer values. *)
AL_LONG = AL_INT64;
(* Unsigned 32/64bit integer values. *)
AL_ULONG = AL_UINT64;
{$ENDIF}
(* size_t equivalent. *)
AL_SIZE_T = AL_UINT64;
(* Fake pointer type. It's needed because the need of pointer arithmetics in
some inlined methods. *)
AL_UINTPTR_T = AL_UINT64;
{$ELSE}
(* Signed 32/64bit integer values. *)
AL_LONG = AL_INT32;
(* Unsigned 32/64bit integer values. *)
AL_ULONG = AL_UINT32;
(* size_t equivalent. *)
AL_SIZE_T = AL_UINT32;
(* Fake pointer type. It's needed because the need of pointer arithmetics in
some inlined methods. *)
AL_UINTPTR_T = AL_UINT32;
{$ENDIF}
(* Float value. *)
AL_FLOAT = SINGLE;
(* Double value. *)
AL_DOUBLE = DOUBLE;
(* Pointer. *)
AL_VOIDptr = AL_POINTER;
(* Special 8bit integer pointer. *)
AL_UINT8ptr = ^AL_UINT8;
(* Pointer to signed 8bit integer values. *)
AL_CHARptr = ^AL_CHAR;
(* Pointer to unsigned 8bit integer values. *)
AL_UCHARptr = ^AL_UCHAR;
(* Pointer to unsigned 16bit integer values. *)
AL_USHORTptr = ^AL_USHORT;
(* Special 16bit integer pointer. *)
AL_UINT16ptr = ^AL_UINT16;
(* Special 32bit integer pointer. *)
AL_UINT32ptr = ^AL_UINT32;
(* Pointer to signed 32bit integer values. *)
AL_INTptr = ^AL_INT;
(* Pointer to signed 32bit integer values. *)
AL_UINTptr = ^AL_UINT;
(* Pointer to float values. *)
AL_FLOATptr = ^AL_FLOAT;
(* Pointer to text strings. Used to convert Pascal's @code(STRING) to C
@code(char * ) *)
AL_STRptr = PCHAR;

BeRo
15-03-2013, 05:32 AM
Just use PtrInt + PtrUInt under FPC and NativeInt + NativeUInt under newer Delphi versions (>= XE2 or so).

SilverWarior
15-03-2013, 05:25 PM
Hi, everybody! I ask for help with transfer of part of a code with C ++ on Delphi. Partially I translated, but I doubt correctness. Files I attach.
In advance, Many thanks!

Hi kordal!
While I might not be of help in translating the provided code (my knowldege od C is bad) I do recognize what code does. It I'm not mistaken the presented code is implementation of 4 octave based Perlin Noise algorithm which is used to proceduraly generate 2D cloud texture.
In the past I was playing some with Perlin Noise and I even found one Pascal implementation. I'm sorry but I don't have the link to it. The main reason for this is the fact that I decided to go and write my own implementation which would provide me with aditional postprocessing to get better results. But I haven't finished my implementation of the algorithm so I can't provide you with it either.
But what I can do is provide you with links to two web pages which decribe how perlin noise works in great detail so they might be of help to you.
http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
http://webstaff.itn.liu.se/~stegu/TNM022-2005/perlinnoiselinks/perlin-noise-math-faq.html
There are several other pages on the web but theese two helped me the most.