![]() |
Forum Index : Microcontroller and PC projects : GFXterm64 for 64-bit Linux
![]() ![]() |
|||||
Author | Message | ||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4044 |
Well... I got 32-bit lazarus with FPC (2.6.4) onto an oldish system. Starts and looks plausible (rather cluttered, though). I guessed I needed to open project1.lpi - seemed happy. Trying Compile got me errors about GetTickCount64 Int64 Not unreasonable :) What next? John |
||||
robert.rozee Guru ![]() Joined: 31/12/2012 Location: New ZealandPosts: 2442 |
hi John, between these two lines: var PAL:array [0..15] of TColor; { TForm1 } add in the following piece of code: // returns an int64 tick counter, based upon GetTickCount with rollover detection function GetTickCount64:int64; const epoch:int64=0; // ticks over in a tad under 50 days DW1:DWORD=0; var DW2:DWORD; begin DW2:=GetTickCount; if DW2<DW1 then inc(epoch, $100000000); DW1:=DW2; result:=epoch+DW2 end; i'm surprised that 32-bit lazarus doesn't already have GetTickCount64 built in, as the 49-day rollover is a bit embarrassing! is the complaint about int64 a warning or an error? cheers, rob :-) |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4044 |
So now it doesn't like GetTickCount (see below) The moan about Int64 has changed and looks like they might be OK (or not?). John unit1.pas(278,23) Error: Identifier not found "GetTickCount" serial.inc(76,16) Hint: Local variable "tios" does not seem to be initialized engine.inc(135,38) Hint: Local variable "n" does not seem to be initialized unit1.pas(433,3) Hint: Converting the operands to "Int64" before doing the multiply could prevent overflow errors. unit1.pas(435,3) Hint: Converting the operands to "Int64" before doing the multiply could prevent overflow errors. unit1.pas(437,3) Hint: Converting the operands to "Int64" before doing the multiply could prevent overflow errors. unit1.pas(439,3) Hint: Converting the operands to "Int64" before doing the multiply could prevent overflow errors. unit1.pas(653,42) Hint: Local variable "buffer" does not seem to be initialized unit1.pas(2106) Fatal: There were 1 errors compiling module, stopping |
||||
robert.rozee Guru ![]() Joined: 31/12/2012 Location: New ZealandPosts: 2442 |
that's odd! try this version instead: function GetTickCount64:int64; const multiplier=24*60*60*1000; begin Result:=trunc(Now*multiplier) end; while simpler, using Now is less desirable as it returns a double-precision float, and so the whole function becomes far more cpu intensive. GetTickCount64 is used quite extensively, so this is not ideal. but it will do for the moment! the other messages, all warnings, should be of no concern. i get similar ones here. cheers, rob :-) |
||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1132 |
This latest version of GFXTerm reminded me to give the program a try. I don't currently have a Linux box running so I'm using the Windows version. I created a little program to test things out - the Game of Life. This runs frighteningly slowly on an Armite F4 so you'll need a lot of patience on a slower micromite. Search for a program named "Golly" for something that runs somewhat faster on various computer platforms. GFXTerm should be run with a larger window size - at least 80x36. This version implements a 40x40 cell world and starts with a simple stick man standing on the bottom of the screen. From there, life takes over. Perhaps the stick man represents John. ' A short test program to play the Game of Life, invented ' by John Conway. Unfortunately, Covid19 took John's life ' on April 11, 2020. His legacy lives on in the coutless ' people inspired by his invention of the cellular automaton ' called the Game of Life and his other works. ' ' Written by vegipete, April 22, 2020 for use with GFXTerm. Option DEFAULT INTEGER Dim INTEGER i,j,count Dim INTEGER xs,ys Dim INTEGER sw,sh Dim string GFX$ Dim float w(41,41) GFX$ = Chr$(16) Print GFX$ "?" ' request size of GFXTerm Window Input sw,sh ' grab dimensions - width and height Print Chr$(27)+"[2J"; ' esc sequence to erase the text screen Print "Thank you John Conway. Rest in Peace." xs = 100: ys = 20 ' clear the world to start For i = 0 To 41 For j = 0 To 41 w(i,j) = 0 Next j Next i ' seed the world w(19,31) = 3 : w(20,31) = 3 : w(21,31) = 3 w(19,32) = 3 : w(21,32) = 3 w(19,33) = 3 : w(21,33) = 3 w(20,34) = 3 w(17,35) = 3 : w(19,35) = 3 : w(20,35) = 3: w(21,35) = 3 w(18,36) = 3 : w(20,36) = 3 : w(22,36) = 3 w(20,37) = 3 : w(23,37) = 3 w(19,38) = 3 : w(21,38) = 3 w(19,39) = 3 : w(21,39) = 3 showWorld Pause 2000 For i = 0 To 1000 ConwayLife showWorld Next i End ' Calculate a new generation of life, using the classic rules Sub ConwayLife Local integer i,j,count ' wrap the corners w(0,0) = w(40,40) : w(41,41) = w(1,1) w(0,41) = w(40,1) : w(41,0) = w(1,40) ' wrap the edges For i = 1 To 40 w(0,i) = w(40,i) ' left w(41,i) = w(1,i) ' right w(i,0) = w(i,40) ' top w(i,41) = w(i,1) ' bottom Next i ' move most recent generation to previous and clear new geneartion For i = 1 To 40 For j = 1 To 40 w(i,j) = w(i,j) << 1 Next j Next i ' calculate new generation For i = 1 To 40 For j = 1 To 40 count = Neighbours(i,j) If (w(i,j) And 2) Then ' was cell alive last generation? ' yes so test if it stays alive If (count = 2) Or (count = 3) Then w(i,j) = w(i,j) + 1 ' cell remains alive for new generation EndIf Else ' no so test if it gets born If count = 3 Then w(i,j) = w(i,j) + 1 ' cell becomes alive for new generation EndIf EndIf Next j Next i End Sub ' return number of neighbours around given point Function Neighbours(x,y) Local count count = 0 If (w(x-1,y-1) And 2) Then count = count + 1 If (w(x+0,y-1) And 2) Then count = count + 1 If (w(x+1,y-1) And 2) Then count = count + 1 If (w(x-1,y+0) And 2) Then count = count + 1 If (w(x+1,y+0) And 2) Then count = count + 1 If (w(x-1,y+1) And 2) Then count = count + 1 If (w(x+0,y+1) And 2) Then count = count + 1 If (w(x+1,y+1) And 2) Then count = count + 1 Neighbours = count End Function ' display the current world Sub showWorld Local integer i,j xstart = 50 Print gfx$ "C" 0,0,sw,sh Print gfx$ "I" 0,0,255,4 For i = 1 To 40 For j = 1 To 40 If w(i,j) And 1 Then Print gfx$ "A" xs+10*i,ys+10*j,xs+6+10*i,ys+6+10*j,0,0 EndIf Next j Next i End Sub End Visit Vegipete's *Mite Library for cool programs. |
||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1132 |
Oops, there's a glitch at the edge of the world in the Game of Life version I just posted above. I'll fix it tomorrow... Visit Vegipete's *Mite Library for cool programs. |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4044 |
GetTickCount64 no seems happy :) Next problem (below) - sorry. Also, I've upset lazarus-ide: all the windows went grey but I don't know what I did. Seems to run, though. edit: quit & reloading fixed the grey. Odd. John Hint: Start of reading config file /etc/fpc.cfg Hint: End of reading config file /etc/fpc.cfg Free Pascal Compiler version 2.6.4 [2016/06/27] for i386 Copyright (c) 1993-2014 by Florian Klaempfl and others Target OS: Linux for i386 Compiling project1.lpr Compiling unit1.pas serial.inc(29,5) Note: Local variable "tios" is assigned but never used serial.inc(76,16) Hint: Local variable "tios" does not seem to be initialized engine.inc(135,38) Hint: Local variable "n" does not seem to be initialized engine.inc(435,12) Note: Local variable "x" not used unit1.pas(428,3) Hint: Converting the operands to "Int64" before doing the multiply could prevent overflow errors. unit1.pas(430,3) Hint: Converting the operands to "Int64" before doing the multiply could prevent overflow errors. unit1.pas(432,3) Hint: Converting the operands to "Int64" before doing the multiply could prevent overflow errors. unit1.pas(434,3) Hint: Converting the operands to "Int64" before doing the multiply could prevent overflow errors. unit1.pas(648,42) Hint: Local variable "buffer" does not seem to be initialized unit1.pas(130,27) Hint: Parameter "Sender" not used unit1.pas(131,27) Hint: Parameter "Sender" not used unit1.pas(132,27) Hint: Parameter "Sender" not used unit1.pas(133,27) Hint: Parameter "Sender" not used unit1.pas(99,28) Hint: Parameter "Sender" not used unit1.pas(98,27) Hint: Parameter "Sender" not used unit1.pas(100,25) Hint: Parameter "Sender" not used unit1.pas(102,48) Hint: Parameter "Shift" not used unit1.pas(107,30) Hint: Parameter "Sender" not used unit1.pas(108,28) Hint: Parameter "MousePos" not used unit1.pas(112,31) Hint: Parameter "Sender" not used unit1.pas(114,31) Hint: Parameter "Sender" not used unit1.pas(115,31) Hint: Parameter "Sender" not used unit1.pas(116,31) Hint: Parameter "Sender" not used unit1.pas(117,30) Hint: Parameter "Sender" not used unit1.pas(120,31) Hint: Parameter "Sender" not used unit1.pas(121,30) Hint: Parameter "Sender" not used unit1.pas(128,31) Hint: Parameter "Sender" not used unit1.pas(93,26) Hint: Parameter "Sender" not used unit1.pas(94,27) Hint: Parameter "Sender" not used unit1.pas(89,46) Hint: Parameter "Sender" not used unit1.pas(90,48) Hint: Parameter "Sender" not used unit1.pas(147,7) Hint: Local const "SoftwareKey" is not used unit1.pas(237,7) Note: Local variable "CPC" not used project1.lpr(17,15) Error: identifier idents no member "Scaled" project1.lpr(23) Fatal: There were 1 errors compiling module, stopping Edited 2020-04-23 16:31 by JohnS |
||||
robert.rozee Guru ![]() Joined: 31/12/2012 Location: New ZealandPosts: 2442 |
you need to comment out (with "//")the line Application.Scaled:=True; in the file project1.lpr as per below: program project1; {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Interfaces, // this includes the LCL widgetset Forms, Unit1 { you can add units after this }; {$R *.res} begin RequireDerivedFormResource:=True; //Application.Scaled:=True; ( <--- this line should be commented out ) Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end. i'm not quite sure why the ide even puts it in there, the option has been set false in the main form anyway. must be something new between the version you are running and the one i have here. btw, all those hints about "Sender" are spurious. every procedure called by an event (which is most) has a pointer to the calling procedure passed in, but this pointer is very rarely used. there is no way to prevent the pointer being passed, as it is a part of the mechanics that ties the whole 'visual engine' of the application together. cheers, rob :-) Edited 2020-04-23 17:58 by robert.rozee |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4044 |
It looks like it probably works... bearing in mind I'm not sure how I'd be sure! I had to take DoubleBuffered = False out of unit1.lfm (I didn't take any other uses of DoubleBuffered out.) I don't understand why it seemed OK before, but no matter. Using Run | Compile it was happy and so was Run | Build. Run | Run gave me a Graphical VT window with a flashing red block cursor, which I'm guessing is right. I don't have anything by way of a 'mite connected, though :) Similarly, if I run the (3.6MB) project1 I also get the VT window with red cursor. file project1 shows it as ./project1: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib, stripped which to me is plausible. Anyone want it? John |
||||
robert.rozee Guru ![]() Joined: 31/12/2012 Location: New ZealandPosts: 2442 |
i'm pretty sure that doublebuffered doesn't do much under linux. within GFXterm it can be turned on/off using the 'undocumented' key combinations ctrl-1 and ctrl-2. with the version of lazarus you are using, i'm picking it can not be set at design time, there are a few differences like that between lazarus and delphi. i'd be keen to play and see how it works - i'm led to believe that modern 64-bit linux distros come with support to run 32-bit executables bundled. feel free to zip it up and upload it here, i much appreciate the effort you've gone to ![]() cheers, rob :-) Edited 2020-04-23 23:39 by robert.rozee |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4044 |
It wasn't much work & you're welcome! Attached. gfxterm32.zip John |
||||
robert.rozee Guru ![]() Joined: 31/12/2012 Location: New ZealandPosts: 2442 |
wow - it works! well, i had to install some extra 32-bit modules, and if run from the console it spits out heaps of warnings while graphics commands are processed. but on-the-whole, pretty much a success. i may need to get a 32-bit VM running at some point to tidy up the loose ends, but my confidence is very much bolstered. cheers, rob :-) |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4044 |
Good to hear! Basically your code was in good shape. John |
||||
robert.rozee Guru ![]() Joined: 31/12/2012 Location: New ZealandPosts: 2442 |
well, this is embarrassing, there was a bug - quite a serious one in terms of usability. if you typed in an incorrect port name when connecting, you'd thereafter be unable to connect to anything until you restarted GFXterm64. and when you restarted it, the incorrect port name would come up as the default. this version fixes that, and includes the fixed serial.inc (where the problem was) in case you want to recompile the source code in the earlier post. GFXterm64 (24-april-2020).zip vegipete: really neat demo, look forward to you fixing the edge issue. hint: rather than counting up the neighbours for each cell (requiring approx 40 x 40 x 8 checks), you may find it quicker to have a second array called Count that is 40 x 40. before each iteration, clear this array (with ERASE Count and re-DIM it, then: 1. scan through w, and for just the cells that are occupied, increment the values in the 8 neighbouring cells of Count. 2. use the values now in Count instead of the function Neighbours(x,y). for a spasely filled 'world' this will be much quicker. cheers, rob :-) Edited 2020-04-24 22:06 by robert.rozee |
||||
![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |