* * *

Author Topic: WINCE slow redraw  (Read 2208 times)

NunoB

  • Newbie
  • Posts: 4
WINCE slow redraw
« on: February 16, 2018, 01:20:46 am »
Hi guys, this is my first post in here, so go easy on me :)

I've been developing a WinCE6 application in my free time. I bought one of those touchscreen chinese car head units with wince a couple of years ago for my 2015 BMW118d, and although it has all functionalities you could imagine, it has some quirks I'd like to solve, by implementing my own software. At least until I decide to move on to an Android unit.

These are the device's specs, according to WR-Tools RESINFO:
Quote
NOWADA
NWD_308 multi-platform 6.0
Windows Embedded CE 6.0
156 MB RAM
ARM11 -308-
800x480, 65536 colors

This baby is capable of reproducing 1080p video content without hickups, but I believe that the original software uses some sort of acceleration.

Anyway, I've been able to reproduce all original functionalities with Lazarus, including COM port habilities (Bluetooth, CANBUS and GPS), and now I'm trying to improve my GUI by adding scroll easing (like easeinoutquad for example) on the main menu.

The problem is that, although easing works, redraw is very slow. It's slow in the emulator, and less slow on the device itself, but still slow, like 2fps.
I've attached a simple example source code with emulator, if any of you is willing to advise, please download it.
Extract it, execute Device_Emulator_Launcher.exe and click on 'Start Device'.
Then, once the emulator starts, navigate to 'My Device'->'StorageCard'->'BMWConcept' and execute bmwconcept.exe.

When the app starts, click on the highlighted button on the attached image.

https://nofile.io/f/rF47wRUVsjc/MicrosoftDeviceEmulator_copy.zip


So, what I'm trying to achieve, is it possible with Lazarus? Or am I trying to do too much with the hardware I've got?

Thanks for your help and your precious time!

donalejo

  • Newbie
  • Posts: 4
Re: WINCE slow redraw
« Reply #1 on: February 20, 2018, 06:48:02 pm »
Hello the problem is use in the proyect this line :

     Application.ApplicationType := atPDA;
Example:

program bmwconcept;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Interfaces, // this includes the LCL widgetset
  Forms, mainform
  { you can add units after this };

{$R *.res}

begin
  RequireDerivedFormResource:=True;

     Application.ApplicationType := atPDA;
  Application.Initialize;
  Application.CreateForm(TMain, Main);
  Application.Run;

end.
                       

Your indicate use the app a PDA, is longer documentation about this.

Saludos desde Argentina

NunoB

  • Newbie
  • Posts: 4
Re: WINCE slow redraw
« Reply #2 on: March 07, 2018, 09:53:45 pm »
Hi, donalejo, thanks for trying to help.

Unfortunately, as soon as I use the ApplicationType directive, the application refuses to run.

This is the output on lcldebug.log:

Quote
[FORMS.PP] ExceptionOccurred
  Sender=EListError
  Exception=Cannot use find on unsorted list
  Stack trace:
  $0004FFB4
  $0017DE94
  $0010D038
  $00103AAC
  $F101FFFC
TApplication.HandleException Cannot use find on unsorted list
  Stack trace:
  $0004FFB4
  $0017DE94
  $0010D038
  $00103AAC
  $F101FFFC
[FORMS.PP] ExceptionOccurred

This happens whether I use atPDA, atDefault or atDesktop.

I tested your suggestion on the example code I posted, where I'm not even using lists, so could this be a bug?

Thanks.

avra

  • Hero Member
  • *****
  • Posts: 1291
    • Additional info
Re: WINCE slow redraw
« Reply #3 on: March 08, 2018, 09:21:51 am »
I tested your suggestion on the example code I posted, where I'm not even using lists, so could this be a bug?
Shouldn't this error text at least ring a bell to you: "Exception=Cannot use find on unsorted list"?
ct2laz - Easily convert components and projects between Lazarus and CodeTyphon

Thaddy

  • Hero Member
  • *****
  • Posts: 6147
Re: WINCE slow redraw
« Reply #4 on: March 08, 2018, 09:39:44 am »
Correct (unless trunk, where I believe it falls back to locate, at least I remember that was discussed on the bug tracker)).
Use locate instead of find. Or sort the list if speed is important.
I might not give the answer that you want me to.. Peter Green 1969

NunoB

  • Newbie
  • Posts: 4
Re: WINCE slow redraw
« Reply #5 on: March 08, 2018, 12:14:51 pm »
I tested your suggestion on the example code I posted, where I'm not even using lists, so could this be a bug?
Shouldn't this error text at least ring a bell to you: "Exception=Cannot use find on unsorted list"?

Sure, that's the first thing I researched. But as I stated, in the simple example I posted, I'm not using TStringList anywhere, sorted or unsorted, much less doing a find. It's just a bunch of panels, a scrollbox and the easing class.
Here's the code of the two files:

mainform.pas:

Code: Pascal  [Select]
  1. unit mainform;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  9.   StdCtrls, easing;
  10.  
  11. type
  12.  
  13.   { TMain }
  14.  
  15.   TMain = class(TForm)
  16.     AudioPlayerPanel: TPanel;
  17.     BluetoothButtonPanel: TPanel;
  18.     ConfiguracaoButtonPanel: TPanel;
  19.     ContentPanel: TPanel;
  20.     FooterPanel: TPanel;
  21.     HomeButton: TImage;
  22.     ClockLabel: TLabel;
  23.     Image1: TImage;
  24.     Image10: TImage;
  25.     Image11: TImage;
  26.     Image12: TImage;
  27.     Image2: TImage;
  28.     Image3: TImage;
  29.     Image4: TImage;
  30.     Image5: TImage;
  31.     Image6: TImage;
  32.     Image7: TImage;
  33.     Image8: TImage;
  34.     Image9: TImage;
  35.     Label2: TLabel;
  36.     Label3: TLabel;
  37.     Label4: TLabel;
  38.     Label5: TLabel;
  39.     Label6: TLabel;
  40.     Label7: TLabel;
  41.     MenuContainerPanel: TScrollBox;
  42.     MenuMainPanel: TPanel;
  43.     MultimediaButtonPanel: TPanel;
  44.     NavegacaoButtonPanel: TPanel;
  45.     PaintBox1: TPaintBox;
  46.     ProgramasButtonPanel: TPanel;
  47.     RepeatPanel: TPanel;
  48.     PlayPanel: TPanel;
  49.     NextPanel: TPanel;
  50.     StopPanel: TPanel;
  51.     ShufflePanel: TPanel;
  52.     AudioPlayerTopPanel: TPanel;
  53.     PreviousPanel: TPanel;
  54.     TrackAlbum: TImage;
  55.     TrackAlbumLabel: TLabel;
  56.     TrackArtist: TImage;
  57.     TrackArtistLabel: TLabel;
  58.     TrackArtworkLarge: TImage;
  59.     TrackArtworkSmall: TImage;
  60.     Label1: TLabel;
  61.     ProgressHandlePanel: TPanel;
  62.     TrackArtistTitleLabel: TLabel;
  63.     MainPanel: TPanel;
  64.     HeaderPanel: TPanel;
  65.     AudioPlayerBottomPanel: TPanel;
  66.     HomeButtonPanel: TPanel;
  67.     ProgressBgPB: TPaintBox;
  68.     TrackBitrate: TLabel;
  69.     TrackGenre: TLabel;
  70.     TrackTitle: TImage;
  71.     TrackTitleLabel: TLabel;
  72.     ViaturaButtonPanel: TPanel;
  73.     procedure BluetoothButtonPanelMouseDown(Sender: TObject;
  74.       Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  75.     procedure BluetoothButtonPanelMouseUp(Sender: TObject;
  76.       Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  77.     procedure ConfiguracaoButtonPanelMouseDown(Sender: TObject;
  78.       Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  79.     procedure ConfiguracaoButtonPanelMouseUp(Sender: TObject;
  80.       Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  81.     procedure FormCreate(Sender: TObject);
  82.     procedure HomeButtonPanelMouseDown(Sender: TObject; Button: TMouseButton;
  83.       Shift: TShiftState; X, Y: Integer);
  84.     procedure HomeButtonPanelMouseUp(Sender: TObject; Button: TMouseButton;
  85.       Shift: TShiftState; X, Y: Integer);
  86.     procedure MultimediaButtonPanelClick(Sender: TObject);
  87.     procedure MultimediaButtonPanelMouseDown(Sender: TObject;
  88.       Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  89.     procedure MultimediaButtonPanelMouseMove(Sender: TObject;
  90.       Shift: TShiftState; X, Y: Integer);
  91.     procedure MultimediaButtonPanelMouseUp(Sender: TObject;
  92.       Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  93.     procedure NavegacaoButtonPanelMouseDown(Sender: TObject;
  94.       Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  95.     procedure NavegacaoButtonPanelMouseUp(Sender: TObject;
  96.       Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  97.     procedure NextPanelMouseDown(Sender: TObject; Button: TMouseButton;
  98.       Shift: TShiftState; X, Y: Integer);
  99.     procedure NextPanelMouseUp(Sender: TObject; Button: TMouseButton;
  100.       Shift: TShiftState; X, Y: Integer);
  101.     procedure PlayPanelMouseDown(Sender: TObject; Button: TMouseButton;
  102.       Shift: TShiftState; X, Y: Integer);
  103.     procedure PlayPanelMouseUp(Sender: TObject; Button: TMouseButton;
  104.       Shift: TShiftState; X, Y: Integer);
  105.     procedure PreviousPanelMouseDown(Sender: TObject; Button: TMouseButton;
  106.       Shift: TShiftState; X, Y: Integer);
  107.     procedure PreviousPanelMouseUp(Sender: TObject; Button: TMouseButton;
  108.       Shift: TShiftState; X, Y: Integer);
  109.     procedure ProgramasButtonPanelMouseDown(Sender: TObject;
  110.       Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  111.     procedure ProgramasButtonPanelMouseUp(Sender: TObject;
  112.       Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  113.     procedure RepeatPanelMouseDown(Sender: TObject; Button: TMouseButton;
  114.       Shift: TShiftState; X, Y: Integer);
  115.     procedure RepeatPanelMouseUp(Sender: TObject; Button: TMouseButton;
  116.       Shift: TShiftState; X, Y: Integer);
  117.     procedure ShufflePanelMouseDown(Sender: TObject; Button: TMouseButton;
  118.       Shift: TShiftState; X, Y: Integer);
  119.     procedure ShufflePanelMouseUp(Sender: TObject; Button: TMouseButton;
  120.       Shift: TShiftState; X, Y: Integer);
  121.     procedure StopPanelMouseDown(Sender: TObject; Button: TMouseButton;
  122.       Shift: TShiftState; X, Y: Integer);
  123.     procedure StopPanelMouseUp(Sender: TObject; Button: TMouseButton;
  124.       Shift: TShiftState; X, Y: Integer);
  125.     procedure ViaturaButtonPanelMouseDown(Sender: TObject;
  126.       Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  127.     procedure ViaturaButtonPanelMouseUp(Sender: TObject; Button: TMouseButton;
  128.       Shift: TShiftState; X, Y: Integer);
  129.     procedure TweenScrollBy(Sender: TObject; startPoint, endPoint: integer;
  130.       Duration: integer; Direction: string; easeType: TChromeTabsEaseType);
  131.   private
  132.     { private declarations }
  133.   public
  134.     { public declarations }
  135.   end;
  136.  
  137. var
  138.   Main: TMain;
  139.   CurrentVisibleMenu: TPanel;
  140.   MouseDownOnMenu: Boolean;
  141.  
  142. implementation
  143.  
  144. {$R *.lfm}
  145.  
  146. { TMain }
  147.  
  148. procedure TMain.HomeButtonPanelMouseDown(Sender: TObject; Button: TMouseButton;
  149.   Shift: TShiftState; X, Y: Integer);
  150. begin
  151.   HomeButtonPanel.Color := $000D70FF;
  152.   Application.Terminate;
  153. end;
  154.  
  155. procedure TMain.HomeButtonPanelMouseUp(Sender: TObject; Button: TMouseButton;
  156.   Shift: TShiftState; X, Y: Integer);
  157. begin
  158.   HomeButtonPanel.Color := $007F7F7F;
  159. end;
  160.  
  161. procedure TMain.BluetoothButtonPanelMouseDown(Sender: TObject;
  162.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  163. begin
  164.   BluetoothButtonPanel.Color := $000D70FF;
  165.   MouseDownOnMenu := True;
  166. end;
  167.  
  168. procedure TMain.BluetoothButtonPanelMouseUp(Sender: TObject;
  169.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  170. begin
  171.   BluetoothButtonPanel.Color := $00666666;
  172.   MouseDownOnMenu := False;
  173. end;
  174.  
  175. procedure TMain.ConfiguracaoButtonPanelMouseDown(Sender: TObject;
  176.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  177. begin
  178.   ConfiguracaoButtonPanel.Color := $000D70FF;
  179.   MouseDownOnMenu := True;
  180. end;
  181.  
  182. procedure TMain.ConfiguracaoButtonPanelMouseUp(Sender: TObject;
  183.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  184. begin
  185.   ConfiguracaoButtonPanel.Color := $004C4C4C;
  186.   MouseDownOnMenu := False;
  187. end;
  188.  
  189. procedure TMain.FormCreate(Sender: TObject);
  190. begin
  191.   CurrentVisibleMenu := MenuMainPanel;
  192.   MenuContainerPanel.DoubleBuffered := True;
  193.   MultimediaButtonPanel.DoubleBuffered := True;
  194.   NavegacaoButtonPanel.DoubleBuffered := True;
  195.   BluetoothButtonPanel.DoubleBuffered := True;
  196.   ProgramasButtonPanel.DoubleBuffered := True;
  197.   ViaturaButtonPanel.DoubleBuffered := True;
  198.   ConfiguracaoButtonPanel.DoubleBuffered := True;
  199. end;
  200.  
  201. procedure TMain.MultimediaButtonPanelMouseDown(Sender: TObject;
  202.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  203. begin
  204.   MultimediaButtonPanel.Color := $000D70FF;
  205.   MouseDownOnMenu := True;
  206. end;
  207.  
  208. procedure TMain.MultimediaButtonPanelMouseMove(Sender: TObject;
  209.   Shift: TShiftState; X, Y: Integer);
  210. begin
  211.   //TPanel(CurrentVisibleMenu).Left := Mouse.CursorPos.X;
  212. end;
  213.  
  214. procedure TMain.MultimediaButtonPanelMouseUp(Sender: TObject;
  215.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  216. begin
  217.   MultimediaButtonPanel.Color := $00666666;
  218.   MouseDownOnMenu := False;
  219. end;
  220.  
  221. procedure TMain.MultimediaButtonPanelClick(Sender: TObject);
  222. begin
  223.   ShowMessage('teste');
  224. end;
  225.  
  226. procedure TMain.NavegacaoButtonPanelMouseDown(Sender: TObject;
  227.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  228. begin
  229.   NavegacaoButtonPanel.Color := $000D70FF;
  230.   MouseDownOnMenu := True;
  231. end;
  232.  
  233. procedure TMain.NavegacaoButtonPanelMouseUp(Sender: TObject;
  234.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  235. begin
  236.   NavegacaoButtonPanel.Color := $004C4C4C;
  237.   MouseDownOnMenu := False;
  238. end;
  239.  
  240. procedure TMain.NextPanelMouseDown(Sender: TObject; Button: TMouseButton;
  241.   Shift: TShiftState; X, Y: Integer);
  242. begin
  243.   NextPanel.Color := $000D70FF;
  244.   TweenScrollBy(CurrentVisibleMenu, -760, 0, 100, 'horizontal', tteaseInOutQuad);
  245. end;
  246.  
  247. procedure TMain.NextPanelMouseUp(Sender: TObject; Button: TMouseButton;
  248.   Shift: TShiftState; X, Y: Integer);
  249. begin
  250.   NextPanel.Color := $00999999;
  251. end;
  252.  
  253. procedure TMain.PlayPanelMouseDown(Sender: TObject; Button: TMouseButton;
  254.   Shift: TShiftState; X, Y: Integer);
  255. begin
  256.   PlayPanel.Color := $000D70FF;
  257. end;
  258.  
  259. procedure TMain.PlayPanelMouseUp(Sender: TObject; Button: TMouseButton;
  260.   Shift: TShiftState; X, Y: Integer);
  261. begin
  262.   PlayPanel.Color := $00B2B2B2;
  263. end;
  264.  
  265. procedure TMain.PreviousPanelMouseDown(Sender: TObject; Button: TMouseButton;
  266.   Shift: TShiftState; X, Y: Integer);
  267. begin
  268.   PreviousPanel.Color := $000D70FF;
  269.   TweenScrollBy(CurrentVisibleMenu, 0, -760, 100, 'horizontal', tteaseInOutQuad);
  270. end;
  271.  
  272. procedure TMain.PreviousPanelMouseUp(Sender: TObject; Button: TMouseButton;
  273.   Shift: TShiftState; X, Y: Integer);
  274. begin
  275.   PreviousPanel.Color := $00B2B2B2;
  276. end;
  277.  
  278. procedure TMain.ProgramasButtonPanelMouseDown(Sender: TObject;
  279.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  280. begin
  281.   ProgramasButtonPanel.Color := $000D70FF;
  282.   MouseDownOnMenu := True;
  283. end;
  284.  
  285. procedure TMain.ProgramasButtonPanelMouseUp(Sender: TObject;
  286.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  287. begin
  288.   ProgramasButtonPanel.Color := $004C4C4C;
  289.   MouseDownOnMenu := False;
  290. end;
  291.  
  292. procedure TMain.RepeatPanelMouseDown(Sender: TObject; Button: TMouseButton;
  293.   Shift: TShiftState; X, Y: Integer);
  294. begin
  295.   RepeatPanel.Color := $000D70FF;
  296. end;
  297.  
  298. procedure TMain.RepeatPanelMouseUp(Sender: TObject; Button: TMouseButton;
  299.   Shift: TShiftState; X, Y: Integer);
  300. begin
  301.   RepeatPanel.Color := $007F7F7F;
  302. end;
  303.  
  304. procedure TMain.ShufflePanelMouseDown(Sender: TObject; Button: TMouseButton;
  305.   Shift: TShiftState; X, Y: Integer);
  306. begin
  307.   ShufflePanel.Color := $000D70FF;
  308. end;
  309.  
  310. procedure TMain.ShufflePanelMouseUp(Sender: TObject; Button: TMouseButton;
  311.   Shift: TShiftState; X, Y: Integer);
  312. begin
  313.   ShufflePanel.Color := $00999999;
  314. end;
  315.  
  316. procedure TMain.StopPanelMouseDown(Sender: TObject; Button: TMouseButton;
  317.   Shift: TShiftState; X, Y: Integer);
  318. begin
  319.   StopPanel.Color := $000D70FF;
  320. end;
  321.  
  322. procedure TMain.StopPanelMouseUp(Sender: TObject; Button: TMouseButton;
  323.   Shift: TShiftState; X, Y: Integer);
  324. begin
  325.   StopPanel.Color := $00CCCCCC;
  326. end;
  327.  
  328. procedure TMain.ViaturaButtonPanelMouseDown(Sender: TObject;
  329.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  330. begin
  331.   ViaturaButtonPanel.Color := $000D70FF;
  332.   MouseDownOnMenu := True;
  333. end;
  334.  
  335. procedure TMain.ViaturaButtonPanelMouseUp(Sender: TObject;
  336.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  337. begin
  338.   ViaturaButtonPanel.Color := $00666666;
  339.   MouseDownOnMenu := False;
  340. end;
  341.  
  342. procedure TMain.TweenScrollBy(Sender: TObject; startPoint, endPoint: integer;
  343.   Duration: integer; Direction: string; easeType: TChromeTabsEaseType);
  344. var
  345.   i, j: integer;
  346. begin
  347.   for i := 1 to Duration do
  348.   begin
  349.     j := Trunc(CalculateEase(startPoint, endPoint, i, Duration, easeType));
  350.     if ((startPoint > endPoint) and (j < endPoint)) or
  351.       ((startPoint < endPoint) and (j > endPoint)) then
  352.       j := endPoint;
  353.  
  354.     case Direction of
  355.       'vertical': TPanel(CurrentVisibleMenu).Top := j;
  356.       'horizontal': TPanel(CurrentVisibleMenu).Left := j;
  357.     end;
  358.  
  359.     TPanel(CurrentVisibleMenu).Update;
  360.   end;
  361. end;
  362.  
  363. end.

easing.pas:

Code: Pascal  [Select]
  1. unit easing;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Math;
  9.  
  10. type
  11.   TChromeTabsEaseType = (
  12.     ttlinearTween,
  13.     tteaseInQuad,
  14.     tteaseOutQuad,
  15.     tteaseInOutQuad,
  16.     tteaseInCubic,
  17.     tteaseOutCubic,
  18.     tteaseInOutCubic,
  19.     tteaseInQuart,
  20.     tteaseOutQuart,
  21.     tteaseInOutQuart,
  22.     tteaseInQuint,
  23.     tteaseOutQuint,
  24.     tteaseInOutQuint,
  25.     tteaseInSine,
  26.     tteaseOutSine,
  27.     tteaseInOutSine,
  28.     tteaseInExpo,
  29.     tteaseOutExpo,
  30.     tteaseInOutExpo,
  31.     tteaseInCirc,
  32.     tteaseOutCirc,
  33.     tteaseInOutCirc
  34.     );
  35.  
  36. function CalculateEase(CurrentTime, StartValue, ChangeInValue, Duration: real;
  37.   EaseType: TChromeTabsEaseType): real; overload;
  38. function CalculateEase(StartPos, EndPos, PositionPct: real;
  39.   Duration: integer; EaseType: TChromeTabsEaseType): real; overload;
  40.  
  41. implementation
  42.  
  43. function CalculateEase(CurrentTime, StartValue, ChangeInValue, Duration: real;
  44.   EaseType: TChromeTabsEaseType): real;
  45. begin
  46.   case EaseType of
  47.     ttLinearTween:
  48.     begin
  49.       Result := ChangeInValue * CurrentTime / Duration + StartValue;
  50.     end;
  51.  
  52.     ttEaseInQuad:
  53.     begin
  54.       CurrentTime := CurrentTime / Duration;
  55.  
  56.       Result := ChangeInValue * CurrentTime * CurrentTime + StartValue;
  57.     end;
  58.  
  59.     ttEaseOutQuad:
  60.     begin
  61.       CurrentTime := CurrentTime / Duration;
  62.  
  63.       Result := -ChangeInValue * CurrentTime * (CurrentTime - 2) + StartValue;
  64.     end;
  65.  
  66.     ttEaseInOutQuad:
  67.     begin
  68.       CurrentTime := CurrentTime / (Duration / 2);
  69.  
  70.       if CurrentTime < 1 then
  71.         Result := ChangeInValue / 2 * CurrentTime * CurrentTime + StartValue
  72.       else
  73.       begin
  74.         CurrentTime := CurrentTime - 1;
  75.         Result := -ChangeInValue / 2 * (CurrentTime * (CurrentTime - 2) - 1) +
  76.           StartValue;
  77.       end;
  78.     end;
  79.  
  80.     ttEaseInCubic:
  81.     begin
  82.       CurrentTime := CurrentTime / Duration;
  83.  
  84.       Result := ChangeInValue * CurrentTime * CurrentTime * CurrentTime + StartValue;
  85.     end;
  86.  
  87.     ttEaseOutCubic:
  88.     begin
  89.       CurrentTime := (CurrentTime / Duration) - 1;
  90.  
  91.       Result := ChangeInValue * (CurrentTime * CurrentTime * CurrentTime + 1) +
  92.         StartValue;
  93.     end;
  94.  
  95.     ttEaseInOutCubic:
  96.     begin
  97.       CurrentTime := CurrentTime / (Duration / 2);
  98.  
  99.       if CurrentTime < 1 then
  100.         Result := ChangeInValue / 2 * CurrentTime * CurrentTime *
  101.           CurrentTime + StartValue
  102.       else
  103.       begin
  104.         CurrentTime := CurrentTime - 2;
  105.  
  106.         Result := ChangeInValue / 2 * (CurrentTime * CurrentTime *
  107.           CurrentTime + 2) + StartValue;
  108.       end;
  109.     end;
  110.  
  111.     ttEaseInQuart:
  112.     begin
  113.       CurrentTime := CurrentTime / Duration;
  114.  
  115.       Result := ChangeInValue * CurrentTime * CurrentTime * CurrentTime *
  116.         CurrentTime + StartValue;
  117.     end;
  118.  
  119.     ttEaseOutQuart:
  120.     begin
  121.       CurrentTime := (CurrentTime / Duration) - 1;
  122.  
  123.       Result := -ChangeInValue * (CurrentTime * CurrentTime *
  124.         CurrentTime * CurrentTime - 1) + StartValue;
  125.     end;
  126.  
  127.     ttEaseInOutQuart:
  128.     begin
  129.       CurrentTime := CurrentTime / (Duration / 2);
  130.  
  131.       if CurrentTime < 1 then
  132.         Result := ChangeInValue / 2 * CurrentTime * CurrentTime *
  133.           CurrentTime * CurrentTime + StartValue
  134.       else
  135.       begin
  136.         CurrentTime := CurrentTime - 2;
  137.  
  138.         Result := -ChangeInValue / 2 * (CurrentTime * CurrentTime *
  139.           CurrentTime * CurrentTime - 2) + StartValue;
  140.       end;
  141.     end;
  142.  
  143.     ttEaseInQuint:
  144.     begin
  145.       CurrentTime := CurrentTime / Duration;
  146.  
  147.       Result := ChangeInValue * CurrentTime * CurrentTime * CurrentTime *
  148.         CurrentTime * CurrentTime + StartValue;
  149.     end;
  150.  
  151.     ttEaseOutQuint:
  152.     begin
  153.       CurrentTime := (CurrentTime / Duration) - 1;
  154.  
  155.       Result := ChangeInValue * (CurrentTime * CurrentTime *
  156.         CurrentTime * CurrentTime * CurrentTime + 1) + StartValue;
  157.     end;
  158.  
  159.     ttEaseInOutQuint:
  160.     begin
  161.       CurrentTime := CurrentTime / (Duration / 2);
  162.       if CurrentTime < 1 then
  163.         Result := ChangeInValue / 2 * CurrentTime * CurrentTime *
  164.           CurrentTime * CurrentTime * CurrentTime + StartValue
  165.       else
  166.       begin
  167.         CurrentTime := CurrentTime - 2;
  168.  
  169.         Result := ChangeInValue / 2 * (CurrentTime * CurrentTime *
  170.           CurrentTime * CurrentTime * CurrentTime + 2) + StartValue;
  171.       end;
  172.     end;
  173.  
  174.     ttEaseInSine:
  175.     begin
  176.       Result := -ChangeInValue * Cos(CurrentTime / Duration * (PI / 2)) +
  177.         ChangeInValue + StartValue;
  178.     end;
  179.  
  180.     ttEaseOutSine:
  181.     begin
  182.       Result := ChangeInValue * Sin(CurrentTime / Duration * (PI / 2)) + StartValue;
  183.     end;
  184.  
  185.     ttEaseInOutSine:
  186.     begin
  187.       Result := -ChangeInValue / 2 * (Cos(PI * CurrentTime / Duration) - 1) +
  188.         StartValue;
  189.     end;
  190.  
  191.     ttEaseInExpo:
  192.     begin
  193.       Result := ChangeInValue * Power(2, 10 * (CurrentTime / Duration - 1)) +
  194.         StartValue;
  195.     end;
  196.  
  197.     ttEaseOutExpo:
  198.     begin
  199.       Result := ChangeInValue * (-Power(2, -10 * CurrentTime / Duration) + 1) +
  200.         StartValue;
  201.     end;
  202.  
  203.     ttEaseInOutExpo:
  204.     begin
  205.       CurrentTime := CurrentTime / (Duration / 2);
  206.  
  207.       if CurrentTime < 1 then
  208.         Result := ChangeInValue / 2 * Power(2, 10 * (CurrentTime - 1)) + StartValue
  209.       else
  210.       begin
  211.         CurrentTime := CurrentTime - 1;
  212.  
  213.         Result := ChangeInValue / 2 * (-Power(2, -10 * CurrentTime) + 2) +
  214.           StartValue;
  215.       end;
  216.     end;
  217.  
  218.     ttEaseInCirc:
  219.     begin
  220.       CurrentTime := CurrentTime / Duration;
  221.  
  222.       Result := -ChangeInValue * (Sqrt(1 - CurrentTime * CurrentTime) - 1) +
  223.         StartValue;
  224.     end;
  225.  
  226.     ttEaseOutCirc:
  227.     begin
  228.       CurrentTime := (CurrentTime / Duration) - 1;
  229.  
  230.       Result := ChangeInValue * Sqrt(1 - CurrentTime * CurrentTime) + StartValue;
  231.     end;
  232.  
  233.     ttEaseInOutCirc:
  234.     begin
  235.       CurrentTime := CurrentTime / (Duration / 2);
  236.  
  237.       if CurrentTime < 1 then
  238.         Result := -ChangeInValue / 2 * (Sqrt(1 - CurrentTime * CurrentTime) - 1) +
  239.           StartValue
  240.       else
  241.       begin
  242.         CurrentTime := CurrentTime - 2;
  243.  
  244.         Result := ChangeInValue / 2 * (Sqrt(1 - CurrentTime * CurrentTime) + 1) +
  245.           StartValue;
  246.       end;
  247.     end;
  248.   end;
  249. end;
  250.  
  251. function CalculateEase(StartPos, EndPos, PositionPct: real;
  252.   Duration: integer; EaseType: TChromeTabsEaseType): real;
  253. var
  254.   t, b, c, d: real;
  255. begin
  256.   c := EndPos - StartPos;
  257.   d := Duration;
  258.   t := PositionPct;
  259.   b := StartPos;
  260.  
  261.   Result := CalculateEase(t, b, c, d, EaseType);
  262. end;
  263.  
  264. end.

Besides, if I compile for win32 and include the ApplicationType directive, the app runs perfectly. When I compile and run for wince and include the ApplicationType directive, the problem arises.
So, if it runs perfectly in wince if I omit the ApplicationType directive, the problem must reside somewhere upstream in one of the includes and is specific for wince?

I'm using Lazarus v1.6.4 with FPC 3.0.2.

Excuse my ignorance, it's been 15 years since I last programmed in Pascal.
« Last Edit: March 08, 2018, 12:21:34 pm by NunoB »

avra

  • Hero Member
  • *****
  • Posts: 1291
    • Additional info
Re: WINCE slow redraw
« Reply #6 on: March 08, 2018, 08:41:38 pm »
That error string is SErrFindNeedsSortedList in rtlconst.inc and can be tracked to a single usage in stringl.inc:
Code: Pascal  [Select]
  1. function TStringList.Find(const S: string; out Index: Integer): Boolean;
  2. ...
  3.   if Not Sorted then
  4.     Raise EListError.Create(SErrFindNeedsSortedList);
  5.  

I'm not using TStringList anywhere, sorted or unsorted, much less doing a find.
It exists somewhere, and is not behaving properly on WinCE. If you are lucky then some of the components you have on the screen has it (memo or something else). Delete one by one to find out in runtime. Even make an empty project to see if it shows. If you are not lucky then problematic string list is not visual and you will have to examine any ancestor of anything you use if it has string list. Backup your project, then rip it off more and more to find what creates the problem. You can also use logging to find what line was last executed before that exception.

Quote
I'm using Lazarus v1.6.4 with FPC 3.0.2.
You can try some older Lazarus (even with FPC 2.6.4), and you can try latest trunks. Maybe something changes in your favor.

Quote
it's been 15 years since I last programmed in Pascal.
Welcome back
ct2laz - Easily convert components and projects between Lazarus and CodeTyphon

NunoB

  • Newbie
  • Posts: 4
Re: WINCE slow redraw
« Reply #7 on: March 12, 2018, 12:41:44 am »
Cheers avra and thanks for your experienced and precious help.
Unfortunately, even an empty project (just a form, no objects) results in the same error, which means this is in fact a bug.
I'll try an earlier Lazarus/FPC, maybe I'll be able to pinpoint the revision where this bug was introduced.

Thanks also to Thaddy who actually realized this is a bug. It must be hard to keep Lazarus compatible with such an outdated OS such as WinCE and it's actually amazing how you guys managed to do this for so long.
I would have used VS and C++, but it's actually hard (if not impossible) to get a VS2005 with WinCE SDK working on a 64bit Win10 system, which is my development machine. It's also as hard to debug, since the emulator is a 32bit application and I wasn't able to get debug to work due to this fact.

That's why I opted for Lazarus, and I must say I'm very impressed with this IDE. Thanks again for all the help, this is an awesome community :)

All the best,

Nuno
« Last Edit: March 12, 2018, 12:53:48 am by NunoB »

avra

  • Hero Member
  • *****
  • Posts: 1291
    • Additional info
Re: WINCE slow redraw
« Reply #8 on: March 12, 2018, 08:39:44 am »
Unfortunately, even an empty project (just a form, no objects) results in the same error, which means this is in fact a bug.
Then you can try to patch TStringList.Find not to raise that exception (maybe just try to return not found result instead), rebuild IDE, and see what happens with newly build empty project. If you play with it a little I think you can achieve enough for your purpose. You have a full source of everything, so you can be as much of a master as you need to.

I'll try an earlier Lazarus/FPC, maybe I'll be able to pinpoint the revision where this bug was introduced.
I would test Laz 1.2 + FPC 2.6.4 (if I remember well it was good on WinCE), but I would also test latest trunk versions of Laz and FPC. You can use fpcupdeluxe (google if you don't know what that is) to download those versions without affecting your current installation at all.
ct2laz - Easily convert components and projects between Lazarus and CodeTyphon

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus