Announcement

Collapse
No announcement yet.

*Documentation*

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • *Documentation*

    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*

  • #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.
    Mark

    Comment


    • #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*

      Comment


      • #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)
        Mark

        Comment


        • #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.
          Mark

          Comment


          • #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*

            Comment


            • #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.
              Mark

              Comment


              • #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:

                HTML 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
                
                
                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*

                Comment


                • #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);
                  Mark

                  Comment


                  • #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*

                    Comment


                    • #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*

                      Comment


                      • #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


                        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.
                        Mark

                        Comment


                        • #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 &amp; 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*



                          Comment


                          • #14

                            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.

                            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 &amp; 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?


                            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.


                            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.


                            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'.


                            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.


                            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.


                            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) ;

                            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&amp;trail=25#3


                            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

                            Comment


                            • #15
                              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.

                              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*

                              Comment

                              Working...
                              X