*Documentation* - 4D SYSTEMS FORUM

(a minor rant)

(This is a reprint of a thread on the 4D Systems support forum, illustrating the frustrating surprises one can run into when trying to use a brand-new product for which support and documentation is woefully lacking, and yet the manufacturer maintains that it is ready for prime-time, production use. The Picaso-uLCD-32032-P1T is a small graphic display unit with a touch screen and a serial interface, as well as a micro-SD slot to allow program and data storage on local FAT-filesystem cards. The intent is that applications for the unit are developed in "4DGL", a high-level graphics-oriented language available as a downloadable kit containing compiler, downloader, and a serial-port debugging interface wrapped up in an integrated development environment.

Slick product idea; still needs significant work on the usability side.     Buyer beware.)

_H*   090331


Search This Thread
   
Advanced Search 
4D SYSTEMS FORUM

Register Login Search New Posts Chat
4D Systems > Forums > 4DGL (4D Graphics Language) > *Documentation*
 
Username:
Password:
 

Thread Tools  | Search This Thread 
Reply
 
Author Comment
 
33hobbit
Registered: 10/03/09
Posts: 13

    11/03/09 at 09:24 AM
Reply with quote #1

I'm just getting started with 4dgl for a project that was sort
of dumped into my lap, and several aspects of this language
are completely kicking my butt despite staring at the examples.
The main problem is that there's no comprehensive manual
for the language in one place. So I sort of made one, by
web-whacking everything from 4dsystems.com.au/developer and
massaging/combining the HTML into something I could easily
read and store local copies of. That was way more work than
I should have to go through to use a programming environment.
Then I saw a reference to "Introducing_4DGL_V2.1.pdf" on some
forum posting, I've lost track of where, which turned out
to be a PDF version of roughly the same thing but evidently
*not* something produced by 4dsystems.
.
Why is this information not in plain sight on the 4dsystems
website, other than in the hundreds of tiny little HTML pages?
.
How much active support for this development system is being
done these days, and is this forum site the main interaction
point for it? I have several other comments/questions about
the language, its interactions, and the support site which
I'll start posting if I have some assurance that it's getting
in front of the right eyeballs.
.
And why are there TWO textboxes in the posting form here??
Only the second one seems to be accepted as a post.
.
_H*
ESPsupport
Moderator
Registered: 27/01/09
Posts: 33

    11/03/09 at 11:54 AM
Reply with quote #2

The documentation is in plain site, just click 4DGL underneath the top banner on any of the web pages.

Of course you are correct and a PDF would often be much handier.

We are actively working on producing such a document and hope it will be available soon.

The PDF you saw was produced by a member of the forum quite some time ago, and is now somewhat dated, although still useful.

And yes, these forums are the correct place to ask questions, so ask away and we will be assisting as much as we can.

As for the TWO Text boxes, I don't know, I just tried to create a new topic and only received one. However, the ISP who maintains this site performed some maintenance over the weekend, adding new features and such and there still appear to be a few gremlins present.
33hobbit
Registered: 10/03/09
Posts: 13

    11/03/09 at 03:10 PM
Reply with quote #3

When learning a new programming language, even if it's a stylistic
variant of several others, it's nice to have all the info in one place.
The way I broke up my collected HTML was by the same topic headings you
use, but opening each one shows me *all* the pages within that topic
at once which is a much easier way to read through things and look up
specifics of a given directive, etc.
.
I'm trying to develop some simple apps on a LCD-32032.
.
I think the thing I'm having the most trouble with is string arguments.
How are strings stored, such that they're NOT usable for various other
calls without messing with str_Ptr first? How is 'str_Ptr(buffer)'
different from 'buffer' or '&buffer'? I want to do something simple
like read an ascii number out of a file, and convert it to an integer
so I can do some math on it ... but the way str_GetW() is documented is
completely confusing. Where do I find a good explanation of the
difference between an array variable that happens to have a string
loaded into it, a "literal string" inlined into the code, and a pointer
presumably derived from taking the address of a variable with &var?
Why are the args to str_GetW() given as "&ptr" and "&var", which in the
former now looks like it's taking a pointer to a pointer? Basically to
get even close to the functionality I expected I had to run through
several permutations of thing, &thing, &thing[0], etc with liberal
"print" statements to try and see what I was getting on the Picaso unit
and I still don't think I understand it. I'm familiar with C pointers
and arrays and structures and this just completely doesn't match,
even with example programs in front of me. A rundown on exactly how
each addressing syntax matches to memory referencing would be a useful
addition to the "basics of the language" set.
.
The webpages describing the functions are really confusing when they
set forth something like
.
file_Read ("*dest", "size", "handle");
Syntax:
file_Read (*dest, size, handle);
Usage:
res := file_Read (memblock, 20, hndl1);
.
First, why do all the page headers place all the arguments in double
quotes? They're not always literal strings. Then, in this example,
why is it '*dest' in one line and NOT '*memblock' in the one right
after it? This sort of mismatch, particularly with '*' and '&',
appears all over the place and leaves the reader with no idea of how
to construct a proper argument list.
.
Like many others, I want to store a bunch of images on the SD card
and display them, likely using a numeric filename fired in over the
serial line. The way I read the documentation, it seemed like I had
to do a file_LoadImageControl() which, guess what, does NOT take a
variable as the filename argument, before I could do a file_Image().
It was only by scanning around the forums that I found discussion from
people who were simply doing file_Open() and passing that handle to
file_Image() and having it work. That is barely documented, if at
all, and completely unclear to someone who has no idea how you're
storing images in the first place. The whole concept of storing
multiple images per file seems klunky at best -- please tell me what
if any advantages there are, in light of having plenty of space on
the card, and nowhere is the actual *format* of a .GCI actually
described -- until someone helpfully posted some details about its
header in another forum posting. When someone is approaching a new
design for a project, what indications do you give them as to the
relative advantages of either using raw-sector offsets on the card,
FAT files with multiple images inside, or separate files with single
images? I think most people would like to stick with image-per-file,
that's what we're most used to. But frankly I dread the prospect of
bumbling my way through GraphicComposer with a mouse to generate
every one of those, assuming file_Image() doesn't support any other
format. Please tell me you can at least read standard windoze .BMPs
or will soon, to spare the industry a whole lot of extra work.
Frankly, there should be no need for GC at all.
.
At one point one of the example programs gets a file handle and then
references hndl[IMG_COUNT] with no explanation what IMG_COUNT is. In
one of the include files I finally found that it means zero, but how
is one supposed to know that that's supposed to give access to the
number of images in a file? Again, complete descriptions of file
structures would be really useful here, as well as details on when
you need a .DAT file and when you don't.
.
I have seen the caveats about "improperly" powering off the display
units in several places. If this is such an issue, why does 4D not
include a little utility, or better yet a switch/button/whatever on
the physical unit, to do just that? When someone is in the throes
of trying to develop software and just as likely to wedge the whole
thing up as be able to download a "proper shutdown" program, there's
no way this is going to get done when the only remaining way to
recover is to yank the plug out of the thing. How many units do you
expect customers to ruin over the course of a typical development
cycle, such that they need to buy more of them for the final project?
That sounds like some kind of planned obsolescence to me.
.
It is very nice to have as much smarts on-board a display unit as
your product line does, and I think I'm trying to set up what will
be a fairly commonplace usage scenario. It took long enough to figure
out the relationship of RAM, "flash", and card storage on this thing;
none of that is described in any introductory material I found and only
obliquely mentioned in some of the program examples. Having to absorb
the particulars of another programming language is one thing, but having
it seem this internally inconsistent is quite another.
.
Finally, I ran into a few places on the 4dsystems website that were
javascript-based links. Those don't work under the way I choose to
run my browsers, and you'll find that a lot more people are disabling
such functionality for security/privacy reasons so there's no good
reason at all to use such constructs in a site design anymore. In
particular, the "downloads" page has this problem and is oddly unlike
most of the other pages at the site.
.
Thanks for any help you can provide; I'd like to see everyone's
projects succeed with the least pain and hopefully all this will
point to some relatively easy product / support enhancements.
While posting to forums is not the right way to write a manual
either, please try to go back through all the questions in this
and hopefully your answers can be fleshed out into additional
documentation sections afterward.
.
_H*
ESPsupport
Moderator
Registered: 27/01/09
Posts: 33

    11/03/09 at 08:48 PM
Reply with quote #4

Here’s the first part of my answers to your questions. I’m not the person who wrote the original documentation, so, hopefully, you will find my answers come from a different perspective and as such, you will be able to use a composite of my answer and the documentation to fully understand what is going on.

Firstly  Str_Ptr, since it was the hardest for me to understand. Visualise an addressing scheme where each address in RAM addresses not 1 but two bytes (i.e. a word). This means that each address contains not one, but two characters. Since we don’t have decimal ½ bytes we need something else for byte addressability, and that something else is str_Ptr.

Secondly the use of & in parameters passed to functions. All parameters passed to functions are words and are unalterable, so, if we need to pass something ‘exotic’, like a string pointer, or something that needs to be altered, you need to pass the address of it, and that’s what the & operator does.

We must thank you for highlighting the many extraneous quotes, ampersands, asterisks. And the often inconsistent usage of them.  4DGL is new, and the documentation is still quite rough around the edges. If it helps, the quoted text was generally designed to help with the (future) dropdown autocomplete in the editor, so the contained text is meant to help you with what the appropriate variable is meant to contain.

My ‘cheat sheet’ for the 4DGL documentation is ‘All parameters are variables or constants (normally), Pointers (if preceded by an & ) and Str_Ptrs (if a string is required)

 

ESPsupport
Moderator
Registered: 27/01/09
Posts: 33

    12/03/09 at 08:12 AM
Reply with quote #5

Onto Images.

Since the display has limited memory resources it makes sense that there are simply not enough resources to process a regular BMP or JPG file and convert it into something that the display can display. This is one of the purposes of GC, to take an image in any format and convert it into the GCI format (V1 is simply data that you could, if you wanted to, build or save using gfx_Get/PutPixel, V2 includes header information that identifies the Xsize, Ysize and Colourmode of the following data).

Similarly, the limited memory affects the processing of FAT files, so to open one file containing many images is far more efficient than to open many files containing a single image. You need to balance the number of images you have against the performance you want. This is also the purpose of file_LoadImageControl and its various modes, to enable you to get the optimal performance for your application.

Another limiting factor of the number of single image files that can be handled is the size of the root directory. There is a discussion on these forums about how to get around that, should that be part of your optimal solution.

Thanks for highlighting the fact that file_LoadImageControl does not handle variables as file names, it will be fixed soon.

FAT files have lower performance than raw sector processing, due to the processing overheads of the FAT and again, the limited memory. Once again, the method you use is dependant upon the performance requirements of your application.

GC gives you a neat way of pulling all your images together, if you find the learning curve scary because your application only needs a few images and you want to put them in separate files, try the img2Gci command line utility that can be found on these forums.

I find using a search tool on the projects folder is a good way to see how to do something that I don’t quite understand. We know lots more examples are needed, and we know the documentation needs enhancement, we are working on both.

Thank you for your interest in what is going on behind the scenes. Most people these days just focus on getting the job done with the tools available without any interest in how the tools actually work.

33hobbit
Registered: 10/03/09
Posts: 13

    12/03/09 at 11:02 AM
Reply with quote #6

Yes, I read the saga of the guy with 1800 astronomical images, but should
go back and review what his solution was. I don't expect to have nearly
that many and a 2 Gb card [that I can lose in the carpet if I'm not
careful!] gives plenty of leeway. I would make a point of emphasizing
in the next round of documentation that file_Open() returns a usable
display handle without the image control stuff, and any caveats or
gotchas that might be associated with doing that.
.
I grabbed "img2gci" and will play with it soon; hopefully it can be a
good companion to a collection of GIMP scripts to batch-reduce arbitrary
source images down to 320x240x16 bitmaps for final treatment. What is
the difference between a .GCI with or without image control data
embedded within? Could a description of the format and its variants
be provided at some point?
.
About memory addressing -- are you saying that each unary location
contains sixteen bits of data, i.e. address 0 holds two bytes, address 1
holds two more bytes, etc? That would break my brain. What does str_Ptr()
actually do with a variable, i.e. how is a linear stream of ascii formed
out of a memory reference and how is that different from &variable? Is
there a diagram of the memory layout and addressing modes anywhere,
perhaps in the spec sheet for whatever processor is in the unit?
.
Thanks for the answers so far. I do like to try and understand things
at a relatively deep level, rather than simply copycatting chunks of
examples and hoping it works. That gives me more insight in to what
can be done in a subsequent project. I also like to be able to
reproduce a workflow -- maybe I generate 20 images today, but how
can I develop a procedure that helps the guy who needs to generate
200 images next week? That sort of thing.
.
_H*
ESPsupport
Moderator
Registered: 27/01/09
Posts: 33

    12/03/09 at 12:24 PM
Reply with quote #7

The caveats about "improperly" powering off the display are necessary. I think you will have seen a description somewhere describing it as being related to the unrestrained ‘flying off the handle’ of the charge pump circuits during an ‘uncontrolled’ power down. You can’t really put a switch in to stop this, it would be too uneconomical. You can’t really code it in software, by the time the power voltage is dropping there probably isn’t enough power left to turn off the charge pumps properly. The damage is long term, in some ways you could look at it as accelerated ageing. It’s the same as removing the batteries of your Laptop / PDA to reset it because it’s stopped responding (have you been warned about that?).

It used to be a corporate policy to have Java Scripts disabled, but I haven’t seen it employed for quite a few years now. Sorry to see you having troubles in the Downloads section, this is one of the older parts of this website and most of the downloads can now be directly accessed from the products pages, so hopefully it will not bother you much more.

Back to memory addressing, yes I am saying that each unary location contains sixteen bits of data, i.e. address 0 holds two bytes, address 1 holds two more bytes. You’ve obviously not looked at some of the newer micro processors/controllers available these days, some of them have 12 bits in each unary location, not worth thinking about. Also, the 8086 did not, truly, allow accesses other than by 16 bits, it was ‘fudged’ by using a line called BHE and had large performance penalties, IIRC. Anyway, I believe str_Ptr works by causing a different kind of access to memory, a more inefficient one that allows 8 bit, bytewise, access.

Viewing forum participant’s profiles is not permitted unless you are a moderator. The developers of this particular forum software have chosen not to allow such access, so I can’t simply change a setting to turn it on, sorry. You can assume that ‘Moderators’ have a fairly close association with 4D, but are not necessarily employed by 4D.

33hobbit
Registered: 10/03/09
Posts: 13

    24/03/09 at 09:58 AM
Reply with quote #8

I have, in fact, been working with PICs in parallel to my
investigation of 4DGL, and do understand the implications of
having memory locations greater than 8 bits wide. That doesn't
help me here. When you say str_Ptr() "gives access" to a linear
stream of bytes, exactly what does that mean? A counterexample
is any of the string routines in PICbasic, where it's pretty clear
that some loop under the covers will be digging the bottom 8 bits
out of many memory locations in sequence and outputting them as a
string. But that is not a process of producing a *pointer* to a
string, it's a process of actually transferring the relevant bytes
to some output device or pin. This does not explain exactly what
str_Ptr() does, as a one-shot call that happens *before* any
output is produced.

Maybe you guys can cut through some of the frustration with this,
especially from today where I've gotten absolutely nowhere on what
should be a relatively simple task. I want to read ASCII numbers
from the serial input, such as "006". I want to do a couple of
things with that input: 1> accumulate the digits as a numeric
variable, e.g. 6, and 2> accumulate the bytes into a string
that I can later concatenate ".GCI" onto and form a filename
of a picture to display. With the way serin() reads characters
into a 16-bit value and the confusion with how a string is
packed, I am UNABLE to do that so far. Furthermore, I am
being thrown by apparent flow logic errors in the language.
Please look at the following admittedly klunky example, which
has mutated over time as I've been trying to debug things:

Code:
var serbuf [80];
var sp;
var hnd;
var x;
var rtotal;
var ifn;
...
// read ascii nums from serial, until CR or LF or whatever
setbaud (BAUD_19200);
x := "-" ;
sp := 0;
rtotal := 0;
print (rtotal, " > ");
while (1)
  x := serin();         // may return -1 if "no char", doesnt block?
  if (x == -1) continue;        // or it runs away off bottom of screen!
  if (x > 0xef) break;          // end on any hi-bit char
  if (x < 16) break;            // any ret/lf/whatever
  if (x == 27) break;           // ESC
/* the ORDER of the tests matters ?? */
  print ([CHR] x, "/", x, ".");
  serbuf [sp++] := x;
  rtotal := (rtotal * 10) + (x - '0');
wend
serbuf [sp] := 0;           // end it


Bug 1: if I send this an ESCape character, the display prints " > "
again and restarts the process of collecting digits. There is NO
logic in my program to do that, as this is all inline in main(), so
clearly the logic of "break" is screwing up somewhere and sending
execution back somewhere earlier in the program where I don't expect.

Eventually I want to turn serbuf[] into a string in "ifn", and do
something like

Code:
to (itemg);
print ([STR]ifn, ".gci");


and do a file_Open() and file_Image() on that. If I manually assign
"ifn" to some pre-existing string, this concatenate-and-open does
work and displays the image file, but assembling this out of serially
read bytes is what I really need to do. I have found nothing in
the Picaso example programs to show me how to do this, either.
It doesn't help that a lot of those examples under "Projects" are
only half-formed, with a lot of dead code and variables that are
never used and very little in the way of useful comments.

This should be totally straightforward, and if I had a clear idea of
what the string functions are doing under the covers with regard
to forming byte streams, I wouldn't have to ask here. But nothing
in my self-generated pseudo "language manual" that I had to bulk
download from your website is telling me this.

Can someone please comment on the long-term viabililty of this product
line? We need to build on something that's actually *supported*.

_H*
ESPsupport
Moderator
Registered: 27/01/09
Posts: 33

    24/03/09 at 12:02 PM
Reply with quote #9

The description of how str_Ptr was simplified, as you have seen from the way PICbasic does it, it is actually far more involved.

Try looking at the way the 4d-spe-v1_1 sample program handles strings (variable Scr_String) hopefully that will help a bit.

You code is behaving as expected, when you send escape you are dropping out of the end of main and 'returning' to the PmmC

You can print your buffer with

    sp:=0;
    while ((x := serbuf[sp++]))  putch(x);


33hobbit
Registered: 10/03/09
Posts: 13

    24/03/09 at 01:55 PM
Reply with quote #10

So to follow the example in SC_GetStr(), I have to manually
shift and fill in both halves of each addressed location, right?
Is that how string constants, i.e. "quoted strings", look in memory
too? Is this consistently little-endian addressing?

Where does SC_GetStr() return a pointer to the stringbuf, as its
comment claims? I see no return (something) statement in that
bit of code, just an endfunc.

While putch() would be fine for text output, how does that help me
build a string buffer in memory to manipulate as a filename?

How is one of several "break" statements inside a "while (1)"
throwing way out past that back to PMMC, rather than simply
exiting the while? This makes no sense. The *other* break
statements nearby do not do that, they simply exit the while()
and proceed to what's next as I would expect -- such as when I
send a CR or LF. As I said, behavior between those different
break conditions is inconsistent, and I haven't seen anything
that says I can't have more than one break per loop.

I realize you guys live and breathe this stuff all day, but you
really have to put this in terms that those relatively unfamiliar
with the language will understand. Especially when you're going
to try and change how people think of pointers and byte streams
and the use of "&" away from what they've done in C for years.
Not being given a clear idea of data storage and how it's manipulated
by various functions, and having to spend a lot of time trying to
independently reverse-engineer it and figure out where all the typos
are in the examples just to gain better understanding, is likely to
chase a lot of developers away from this.

_H*
33hobbit
Registered: 10/03/09
Posts: 13

    25/03/09 at 09:20 AM
Reply with quote #11

Okay, give this an eyeball. I tried to simplify it and explicitly
wrap each character-test clause in its own if/endif, as well as
completely separating out the character-collection routine.
Code:
#platform "uLCD-32032-P1T"
// top level
#inherit "4DGL_16bitColours.fnc"
var serbuf [80];
var sp;
var sph;
var x;
var rtotal;
var ifn;

/* packs serbuf, accumulates rtotal */
func getparm ()

sp := 0;  sph := 0;
while (sp < 19)                 // small buffer limit
  while ((x := serin()) < 0) ;  // wait for valid chars [16-bit values]
  if (x > 0xef)                 // hibits [pic RFID cmd chars?]
    break;
  endif
  if (x < 16)                   // any ret/lf/whatever
    break;
  endif
  if (x == 27)                  // ESC for additional tests
    break;
  endif
  print ([CHR] x, "/", x, ".");
  if (sph)
    serbuf [sp] := (serbuf [sp] | (x << 8));    // high byte
    sp++;
    serbuf[sp] := 0;            // pre-zero next
    sph := 0;
  else
    serbuf[sp] := x;            // low byte
    sph++;
  endif
  rtotal := (rtotal * 10) + (x - '0');
wend

endfunc

func main ()

while (!file_Mount())
    print("Flash card not installed?\n");
    pause (5000);
wend

setbaud (BAUD_19200);
txt_Set (2,1);
rtotal := 0;
print (rtotal, " > ");
pause (1000);

getparm();

print ("\nasc total", rtotal, " len ", sp, "\n");
print ("serbuf @ ", serbuf, " ", [STR]str_Ptr(serbuf), "\n");

repeat forever;            // just hang here

endfunc

I download this to a file on the SD card instead of RAM, since
invoking the serial "debug" box does a reset, and have your
"FAT16runprog" loaded to flash as the top-level when the unit
starts up. I then set the "debug" box to 19200, invoke the
little program above, and start typing stuff. It begins by
displaying "0 > " on the screen, which I see. As I type digits,
I see the appropriate debugging feedback with the ascii and
decimal values of "x". I'm trying to build both an assembled
numeric value *and* a pre-terminated ascii string from the incoming
digits, as both will have uses in the surrounding application.

Examine getparm() carefully. If I send some digits and an ESCape,
the routine terminates character collection and returns.

If I send anything else that's being checked for, such as a
high-bit $F0 - $FF or a return/linefeed/whatever, I see my
"0 > " again, indicating that the program has somehow completely
RESTARTED itself with "rtotal" back to zero.

Where's the logic error here??

In other news, now that I'm keeping track of low vs. high order bytes
and packing them into string variables myself, that seems to be forming
usable strings correctly. I wish your documentation made it very very
clear that that is what's needed, because such operations must be
quite common and such a simple thing should NEVER throw a programmer
so far off track as this has. But now it looks like I'm up against
flat-out bugs in the language. Surely the "while (...) ;" isn't the
problem, as I see such constructs all over the [working] examples??

_H*
ESPsupport
Moderator
Registered: 27/01/09
Posts: 33

    25/03/09 at 10:38 AM
Reply with quote #12

Congrtulations and thank you, you have found a bug in the compiler! As a temporary work around ensure there is only one break statement within a while statement, like this


Quote:
 
  if (   (x > 0xef)     // hibits [pic RFID cmd chars?]
      || (x < 16)       // any ret/lf/whatever
      || (x == 27) )    // ESC for additional tests
    break;
  endif


We will be endeavoring to include examples about string building in the 4DGL programmers manual. The way the manual is currently displayed on the web, perhaps makes the language seem far simpler than it really is, the current draft manual is over 300 pages long.

33hobbit
Registered: 10/03/09
Posts: 13

    26/03/09 at 10:29 AM
Reply with quote #13

I think I found another one. This snippet:
Code:
func showme (fname)
hnd := file_Open (fname);
if (file_Error())
print ("oops: ", fname, "\n");
return;
endif
file_Image (0, 0, hnd);
file_Close (hnd);
endfunc

produces errors at the "return;", claiming that there's no
matching "endif". Sorry to break it to you guys, but this is
a very common coding construct and I find it utterly astounding
that your compiler doesn't accept it.

After carefully going back through your examples looking for
instances where someone may have gotten it to work, it turns out
that any time you have a return in a routine it's always right
down at the end before "endfunc" so it's outside any loops or
if/then blocks. Was this intentional or just dumb luck? I cannot
imagine how someone thought that returning early in one or more
places in a called function isn't perfectly valid logic.

=======

Do you have any idea what a frustrating journey this has been for
me overall? Compiler bugs, flow that should be valid syntax but
isn't, bizarre use of & and * and inconsistent documentation and
appearance, etc.

I have completely given up on str_Ptr() because
I *still* don't understand what it does after looking at reams of
debugging output printed in various different ways and NOT getting
any answers from you guys. All it seems to do is multiply an
address reference by two but there's got to be more to it than
that.

You claim to be able to play .wav files and then it turns
that it's only special kinds of .wav files, and meanwhile I get
half deafened by the results of trying. Well, how 'bout a "Sound
Composer" to go along with GC and reliably produce your favored
file format?

While needing to frequently download to a file on the
SD card instead of RAM, every time I compile a piece of code it
automatically trashes whatever was in the "download" box from the
last run and makes it default back to FUNTEST.4XE for some
inexplicable reason. When I go to open any file in the IDE, the
path ALWAYS starts in the installation directory and I have
to work my way with ".." back up and over to where my stuff
is. EVERY freakin' time.

Do you have ANY notion of how that gets
in the way of the typical quick-edit/compile/load/try-it cycle??
Not to mention that trying to download with the "debug" window still
open someplace has a certain likelihood of corrupting the FAT
filesystem on the card, which I fortunately managed to recover
with CHKDSK.

Please consider command-line versions of these tools, which the
user can wrap batch jobs around and get through REALLY fast. And
stickier defaults / remembered-settings on the GUI ones.

And just today I found out you still don't support landscape image
display at all, even backed up by a barely apologetic forum posting
about it that I finally ran across that keeps mumbling about "next
release". Well, guess what, all the images I have to display are
already in landscape mode, which means I have to 90 them all in an
external image editor before feeding them to that horrendous GC
interface, which I'll add insists on building a new <image>.gci.d
DIRECTORY for every image file I run through it which I then have to
go clean up. Why?? Do that when I say "collect files", not before.

We'll stumble our way through this project somehow, I imagine, but
you have cost us way more time and headache that anyone deserves with
this as it's clearly not ready for public production yet. "Beta" is
a poor excuse when the GL is pretty much the only way to get this
unit to actually do something and some of us have real-life
deadlines.

Perhaps when the language grows up and figures out whether
it wants to be BASIC or C or Pascal or wherever it's trying to head, it
will become something people [besides thomasW69!] would actually want
to develop against. Compared to the PICBasic piece to build what's
going to drive the 4D unit, which I'll add is the FIRST time I've ever
touched PICBasic, the difference in workflow and success rate has
been night and day.

_H*

meldavia
Moderator
Registered: 18/03/07
Posts: 223

    27/03/09 at 01:28 PM
Reply with quote #14

Quote:

I think I found another one. This snippet:
Code:
func showme (fname)
hnd := file_Open (fname);
if (file_Error())
print ("oops: ", fname, "\n");
return;
endif
file_Image (0, 0, hnd);
file_Close (hnd);
endfunc

produces errors at the "return;", claiming that there's no
matching "endif". Sorry to break it to you guys, but this is
a very common coding construct and I find it utterly astounding
that your compiler doesn't accept it.

Your example code actually has quite a few syntax and context errors, apart from the fact that you are trying to close a file with no handle if the function fails (although this would not cause a problem). Yes there seems to be a problem there, thanks for pointing it out, the problem has not been reported before, would not suggest to anyone to code like that - therefore no examples show it that way, however, you are correct and have found a problem with the compiler. It seems that a break statement within an if block is generating incorrect code in some circumstances.

The corrected code and workaround is here:-


Code:
func showme (fname)
var hnd;
hnd := file_Open (fname, 'r');// open image file

if (file_Error())
print ("oops: ", [STR] fname, "\n");// error msg if no good
else
file_Image (0, 0, hnd);// else show the image
file_Close (hnd); // success, close the file
endif
endfunc


As well, the compiler is generating a slightly erroneous error (like many compilers do) - generating a more meaningful error is now lodged in the 'todo' box thanks to your thoughtful input. We are currently doing a a compiler overhaul and it will receive immediate attention. We will send you a new compiler DLL early next week for you to try that will resolve this issue.

Quote:

After carefully going back through your examples looking for
instances where someone may have gotten it to work, it turns out
that any time you have a return in a routine it's always right
down at the end before "endfunc" so it's outside any loops or
if/then blocks. Was this intentional or just dumb luck? I cannot
imagine how someone thought that returning early in one or more
places in a called function isn't perfectly valid logic.

=======

Do you have any idea what a frustrating journey this has been for
me overall? Compiler bugs, flow that should be valid syntax but
isn't, bizarre use of & and * and inconsistent documentation and
appearance, etc.

Yes it must be frustrating - have you tried to understand any of the examples or are you just trying to write code expecting to understand how it works from your vast programming skills?

Quote:

I have completely given up on str_Ptr() because
I *still* don't understand what it does after looking at reams of
debugging output printed in various different ways and NOT getting
any answers from you guys. All it seems to do is multiply an
address reference by two but there's got to be more to it than
that.

EVE is a virtual machine, the notion of a string pointer should not be confused with other languages. 'memory' for strings, being virtual, can come from other sources, and the operation of the str_Ptr() function varies as required at runtime. If you would care to point out to us which examples you have tried which don't work, or some code that you have written that you can't get to function properly, we would always be happy to help.
 

Quote:

You claim to be able to play .wav files and then it turns
that it's only special kinds of .wav files, and meanwhile I get
half deafened by the results of trying. Well, how 'bout a "Sound
Composer" to go along with GC and reliably produce your favored
file format?

The wave file required is in canonical format as previously described. We are not trying to create a multimedia machine, therefore, there is only support for the basic (historical) format which most sound editing programs can produce. Please send us a sample of what you are trying to play, and we will let you know where you have gone wrong.


Quote:

While needing to frequently download to a file on the
SD card instead of RAM, every time I compile a piece of code it
automatically trashes whatever was in the "download" box from the
last run and makes it default back to FUNTEST.4XE for some
inexplicable reason. When I go to open any file in the IDE, the
path ALWAYS starts in the installation directory and I have
to work my way with ".." back up and over to where my stuff
is. EVERY freakin' time.

It seems like you may be bypassing the project manager for some reason. There will be improvements to the IDE soon which will make it more 'idiot proof'.


Quote:

Do you have ANY notion of how that gets
in the way of the typical quick-edit/compile/load/try-it cycle??
Not to mention that trying to download with the "debug" window still
open someplace has a certain likelihood of corrupting the FAT
filesystem on the card, which I fortunately managed to recover
with CHKDSK.

Hmm sounds like your having a really bad time. Your report on that problem has been lodged, we will look into it immediately, although we have had no other posts with a similar problem. Have you thought of the possibility that your code is crashing somehow and corrupting the card? It seems unlikely that it could get corrupted in the manner you have described.


Quote:

Please consider command-line versions of these tools, which the
user can wrap batch jobs around and get through REALLY fast. And
stickier defaults / remembered-settings on the GUI ones.

Yes - fully agreed - command line version is being developed as we speak.


Quote:

And just today I found out you still don't support landscape image
display at all, even backed up by a barely apologetic forum posting
about it that I finally ran across that keeps mumbling about "next
release". Well, guess what, all the images I have to display are
already in landscape mode, which means I have to 90 them all in an
external image editor before feeding them to that horrendous GC
interface, which I'll add insists on building a new <image>.gci.d
DIRECTORY for every image file I run through it which I then have to
go clean up. Why?? Do that when I say "collect files", not before.

The GC is continually being improved but still has no rotate feature. You can rotate images when using the 4DGL Image Control if required by using the gfx_Set(SCREEN_MODE, ...) function. Landscape mode has been supported for quite a while now, gfx_Set(SCREEN_MODE,LANDSCAPE) ;

Quote:

We'll stumble our way through this project somehow, I imagine, but
you have cost us way more time and headache that anyone deserves with
this as it's clearly not ready for public production yet. "Beta" is
a poor excuse when the GL is pretty much the only way to get this
unit to actually do something and some of us have real-life
deadlines.

You may wish to try loading the SPE serial emulator so you can just send serial commands from a host processor. The code is also a good insight into the workings of 4DGL.
SPE info is at http://www.websitetoolbox.com/tool/post/4d/vpost?id=3158442&trail=25#3


Quote:

Perhaps when the language grows up and figures out whether
it wants to be BASIC or C or Pascal or wherever it's trying to head, it
will become something people [besides thomasW69!] would actually want
to develop against. Compared to the PICBasic piece to build what's
going to drive the 4D unit, which I'll add is the FIRST time I've ever
touched PICBasic, the difference in workflow and success rate has
been night and day.

_H*

If you would make your posts single subject, i'm sure you would get lots of help from other forum members and our staff. It is always a daunting task to read through your texts of epic proportions. The reason for these forums is for constructive critisism so we can take valid inputs from our users and try and fix/make things better.

Also, you mention '...NOT getting any answers from you guys.." We have responded to all your emails, and they bounced back. If you are looking for email responses you need to provide a valid email address and a decent name instead of "_H*", otherwise it may end up in the spam bin.


On a final note, we all know how frustrating it can be when things dont work, but if you would care to be a little bit more courteous we will actually go out of our way to help. It is not uncommon for us to fix any urgent problems reported and deliver a 'personalized PmmC' or whatever so you can check it out before it goes to the next release stage.


__________________
Regards,
Dave
33hobbit
Registered: 10/03/09
Posts: 13

    30/03/09 at 02:16 AM
Reply with quote #15

Quote:
Your example code actually has quite a few syntax and context errors,
apart from the fact that you are trying to close a file with no handle if the
function fails

Not if the early "return" worked, of course. Sorry, I typed this in from
faulty memory as I didn't have the actual file I was working on in front of
me at the time. I should probably have "func showme (var fname)" instead,
too, but you get the idea. I had already changed my code to about what
you suggested -- putting everything under a file_Error() if/then.

In the posted 4D-SPE-V1_0mv.4dg you referenced, in the function
ScrDisplayCtrl(), you have an "early return" but it's right after a
gosub. It apparently works there; it's not inside an if/then though.

I *have* spent quite a while trying to understand the examples. As I
pointed out earlier, some of them are half-formed, with blocks of code
commented out and "fix this later" or "this works around a bug" sorts of
items inside and frankly insufficient commentary about how "fred" and
"barney" and such are really being processed. I actually pulled every
one of your example files into one big one just so I could search the
entire codebase for things, such as "str_Ptr", to see where and how it's
being used. From that I still cannot determine the right way to do a
relatively simple thing that's commonplace in C -- pick single bytes
out of a string buffer and pass easily-modifiable pointers around. Let's
say I have a little buffer I just read some ascii into off the serial port,
using a simple protocol of an initial key-letter and then digits following.
I want to make some decision based on the key-letter and then pass the
REST of the string to something else that will parse the digits and do
something useful with them -- in pseudo-C, that is:
Code:
char buf [80];
char * p;
char key;
...
read_serial_and_terminate (buf);
p = &buf[0];            /* point to it */
key = *p;               /* grab the leading key / command char */
switch (key) {
        ...             /* make some decisions based on that */
                        /* (could also just be a chain of if/thens) */
}
p++;                    /* point to REMAINDER of string */
i = atoi (p);           /* turn into integer value */
printf ("digits were %s\n", p);
/* continue handling the ascii digits in some manner */

which is done all the time in programming environments I'm used to but as
much as I've tried to understand how to do this with str_Ptr(), I keep
not getting expected results. Can you supply a snippet that does the
equivalent and gives me usable byte-level handling? You can ignore the
atoi() since I don't think you supply such a function, but the rest as
far as processing strings byte-by-byte is what I've been wrestling with.
The main thing is that once I've incremented "p" to point to the rest of
the string, I want to do things like build filenames out of that or display
the digits on the screen or whatever. This doesn't take vast programming
skills, it's straight out of K&R.

Quote:
EVE is a virtual machine, the notion of a string pointer should not be confused with other languages.

What is "EVE"?

I'm not sure what you mean by the "project manager"; I'm running your IDE
and pressing the "compile" and then "download" buttons. The little
download box pops up and I use to ship the code to the uLCD. What else
should I be doing? It's there that frustration arises because every time
I compile in the main IDE window, the selection of "save to FILE" and the
filename over in the download box CHANGES and reverts to "save to RAM"
instead, and further reverting to FUNTEST.4XE when I go over to it and
re-select "save to FILE". Without me having touched the download box;
this immediately happens upon simply compiling the code.

I think the card filesystem problem was due to timing, between starting a
download and fooling with the Debug window so the download process may
have gotten interrupted. In any case, my file didn't show up and CHKDSK
freed up some lost clusters that presumably would have been its contents
had things completed properly. I still find it odd that opening the
serial "debug" window resets the entire unit, instead of simply beginning
character communication with the serial port.

When I do gfx_Set(SCREEN_MODE, LANDSCAPE) and try to display a 320x240
image, I get a mangled blob of bits at the lefthand edge [in portrait
mode] of the display. The gfx_Set() appears to only affect text and
drawing-primitives, not image files or at least not in a correct way.
The thread at
http://websitetoolbox.com/tool/post/4d/vpost?id=3005256
seems to confirm that. I wouldn't have to rotate all the source
images if gfx_Set() did what I'd expect -- rotate the reference frame
for *everything* and redefine the top-left corner at the new place.

There are just too many surprises for someone starting out using these
products. Rather than spawn off a bunch of other threads I've been sort
of deliberately keeping all this under this one, as it really is largely
about documentation and others can come along later and read the whole
story-line of one person's encounter with 4DGL in one convenient place.
Yes, despite my tendency to rant at length I am thinking about value
(however dubious) to those who come along later.

I don't know what you're referring to with regard to email. The only email
relevance to any of this was to get the forum account set up, which worked
fine as far as I can tell; I have kept all other interactions here in the
forum as it seems to be your preferred means of interacting with the
customer base. I provided a real email address at signup time, and your
messages about getting that finalized did NOT bounce as I received and
responded to them. Are you talking about something subsequent? What were
the error messages in any such bounces? I'll point out that I have had
that same email address since 1994 or thereabouts, and have been signing
my messages off with "_H*" since long before that. Any such "decent name"
can be found at the header of any post, where I'm some random username
on your forum just like "ESPsupport" or "mvandere" or anyone else. That
doesn't tell me anything more about post submitters, especially when your
forum denies attempts to look up someone's profile for more information.

_H*
Previous Thread | Next Thread
Reply