Page 2 of 2 FirstFirst 12
Results 11 to 17 of 17

Thread: datetostr, sounds simple....

  1. #11
    PGD Community Manager AthenaOfDelphi's Avatar
    Join Date
    Dec 2004
    Location
    South Wales, UK
    Posts
    1,245
    Blog Entries
    2

    datetostr, sounds simple....

    Like I said... according to the documentation, to get hardware acceleration, you need do3D, doDirectX7Mode, doHardware.

    Code:
          If HardwareSwitch Then
          {hardware}
          Begin
            if NOT (doDirectX7Mode in DXDraw.Options) then
              DXDraw.Options := DXDraw.Options + [doDirectX7Mode];
            if NOT (doHardware in DXDraw.Options) then
              DXDraw.Options := DXDraw.Options + [doHardware];
            if NOT (do3D in DXDraw.Options) then
              DXDraw.Options := DXDraw.Options + [do3D];
            if doSystemMemory in DXDraw.Options then
              DXDraw.Options := DXDraw.Options - [doSystemMemory];
          End
    Thats just a snippet from the documentation.

    Whether its changed for unDelphiX 1.0.7 I don't know.
    :: AthenaOfDelphi :: My Blog :: My Software ::

  2. #12
    PGD Community Manager AthenaOfDelphi's Avatar
    Join Date
    Dec 2004
    Location
    South Wales, UK
    Posts
    1,245
    Blog Entries
    2

    datetostr, sounds simple....

    Updated the archive containing the sample so the form should be positioned centrally on the screen.
    :: AthenaOfDelphi :: My Blog :: My Software ::

  3. #13

    datetostr, sounds simple....

    Well that's bad. i don't wanna use dx7/Hw mode if it ruins the dates maybe another job for jaro

  4. #14
    PGD Community Manager AthenaOfDelphi's Avatar
    Join Date
    Dec 2004
    Location
    South Wales, UK
    Posts
    1,245
    Blog Entries
    2

    datetostr, sounds simple....

    I guess the question is are dates crucial? Losing hardware acceleration might be a real pain in the ass.

    Anyhow, I've been tinkering, and I've made some interesting discoveries. I created local copies of some of the crucial routines. The majority of them appear to work correctly. The problem appears to be in converting TDateTime to TTimeStamp.

    So... with much tinkering, I have a possible solution...

    Basically, I've created versions of the key routines that only work on Integers and it appears to work (even when pushing in float date using trunc() that would break the standard routines).

    [pascal]
    function intDateTimeToTimestamp(DateTime:integer):TTimestam p;
    var
    temp : cardinal;
    begin
    temp:=dateTime*86400;
    result.date:=DateDelta+(temp div 86400);
    result.time:=temp-result.date;
    end;

    procedure LocalDivMod(Dividend: Integer; Divisor: Word;
    var Result, Remainder: Word);
    asm
    PUSH EBX
    MOV EBX,EDX
    MOV EDX,EAX
    SHR EDX,16
    DIV BX
    MOV EBX,Remainder
    MOV [ECX],AX
    MOV [EBX],DX
    POP EBX
    end;

    function LocalIsLeapYear(Year: Word): Boolean;
    begin
    Result := (Year mod 4 = 0) and ((Year mod 100 <> 0) or (Year mod 400 = 0));
    end;

    const
    LocalMonthDays: array [Boolean] of TDayTable =
    ((31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
    (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31));

    procedure intDecodeDate(Date: Integer; var Year, Month, Day, DOW: Word);
    const
    D1 = 365;
    D4 = D1 * 4 + 1;
    D100 = D4 * 25 - 1;
    D400 = D100 * 4 + 1;
    var
    Y, M, D, I: Word;
    T: Integer;
    DayTable: PDayTable;
    begin
    T := IntDateTimeToTimestamp(date).date;
    if T <0>= D400 do
    begin
    Dec(T, D400);
    Inc(Y, 400);
    end;
    LocalDivMod(T, D100, I, D);
    if I = 4 then
    begin
    Dec(I);
    Inc(D, D100);
    end;
    Inc(Y, I * 100);
    LocalDivMod(D, D4, I, D);
    Inc(Y, I * 4);
    LocalDivMod(D, D1, I, D);
    if I = 4 then
    begin
    Dec(I);
    Inc(D, D1);
    end;
    Inc(Y, I);
    DayTable := @LocalMonthDays[LocalIsLeapYear(Y)];
    M := 1;
    while True do
    begin
    I := DayTable^[M];
    if D < I then Break;
    Dec(D, I);
    Inc(M);
    end;
    Year := Y;
    Month := M;
    Day := D + 1;
    end;
    end;
    [/pascal]

    The only real requirements for this are that if you are using TDateTime values, you pass them into the routine using trunc(datetime).

    I can't guarantee that this is going to work with every date because the original DateTimeToTimestamp routine is written in assembler and my x86 is VERY poor, so whilst it works (using my test data) it may not be correct for other dates. There is some kind of conditional negation I think in the routine... I don't have that, so certain date ranges could go bang.

    But, these routine do appear to work in my test bed.

    I think the reason is because (from what I can tell) once you call the intDecodeDate routine, there are no floating point instructions such as FMul which are present in the orginal versions.

    I'm guessing from this that somewhere along the lines, unDelphiX or DirectX changes some flags or settings in the FPU that breaks standard routines.

    Anyhow.... hope this helps.

    As a side note... if someone in the know could possibly explain why this problem is occuring, I'm sure seiferalmasy would appreciate it, because I know I would :-)
    :: AthenaOfDelphi :: My Blog :: My Software ::

  5. #15

    datetostr, sounds simple....

    well, thats nice and you are right...i do want to know why, and i want it fixed :lol:

  6. #16

    datetostr, sounds simple....

    Maybe could help disabling optimization before the asm function and reenabling it after with {$O-} and {$O+}.
    I'm wondering about registers used too. In free pascal you can tell to compiler the registers used, so it will preserve them, though I'm not sure about delphi:

    [pascal]procedure foo (value: longint); assembler;
    asm
    mov ebx, eax
    ...
    ...
    end ['ebx'];
    [/pascal]

    :think:
    Get your fpc4gba copy now!
    Get your fpc4nds copy now!

  7. #17
    PGD Community Manager AthenaOfDelphi's Avatar
    Join Date
    Dec 2004
    Location
    South Wales, UK
    Posts
    1,245
    Blog Entries
    2

    datetostr, sounds simple....

    Its a very strange issue... not that it affects me (at the moment), but it got me thinking. As soon as you enable DirectX, even the most basic of operations on the variables report strange values....

    For example, floatToStr(myVar) (myVar contains 1.0) will report 1 before, and then 0.9999999something or other after DirectX has been initialised with TDXDraw.initialize.
    :: AthenaOfDelphi :: My Blog :: My Software ::

Page 2 of 2 FirstFirst 12

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •