
          [32;43m                              [31;40m
          [32;43m     From DPaint Brushes      [31;40m
          [32;43m     to BASIC Object Files    [31;40m
          [32;43m                              [31;40m

                                 [3;33;40mBy John Collett[0;31;40m


[3m    Ed: For more along these lines, check out also "ColourTool" in this
[3m    drawer.

[32m    ## 24 ## 24 ## 24 ## 24 ## 24 ## 24 ## 24 ## 24 ## 24 ## 24 ## 24 ##


    [32;41m    Remote Background    [31;40m

    Long ago, I had hacked together various bits and pieces from the
    Extras disk to create a program which would load in an IFF file
    such as a DPaint brush and output an object file for use with
    OBJECT, GET, and PUT commands in Basic.  It was limited in scope,
    not very reliable, contained much that I didn't understand, and
    had some really nasty patches of code, but was occasionally
    useful.

    One or two of my books on AmigaBasic offered "Brush to Object"
    code which I copied very carefully but could never get to work.
    Every other combination of "x TO y" seemed to appear on PD disks
    and MegaDisc, but if there was a "Brush to BasicObject" program
    offered, I missed it.

    I managed with my own program, but always hoped that something
    better would appear.


    [32;41m    Recent Background    [31;40m

    I obtained a copy of Jonathan Potter's Image-Ed (Fish Disk 412),
    and thought I had the answer, but somehow I couldn't get that
    particular function of an otherwise excellent program to work. I
    sent a donation towards JP's retirement fund, and obtained the
    full documentation.  It states clearly that a brush can be loaded
    in and then saved as a Basic Bob, but I still can't get it to
    perform as promised and expected in that one respect.  I'm
    probably doing something wrong.

    In Readers' Queries (MD 23) came a request from Gwyn Morfey of
    Adelaide, asking how to load an IFF file from DeluxePaint for use in
    Basic programs.  I dug out some of my earlier untidy pieces
    and posted them in the Perth direction, only sorry that they were
    not more adequate.

    At about the same time I had been exploring the "LoadIff" command
    in Hisoft Basic, and regretting the absence from that language of
    a similar "LoadBrush" command for less than full screens.


    [32;41m    A HiSoft Version of "BrushToObject"    [31;40m

    There comes a time when hoping, waiting, and regretting are just
    not enough, and in a fairly earnest frame of mind I settled down
    to write a BrushToObject program in HiSoft Basic. The following
    stages were envisaged:

       Load the selected IFF brush on to the screen.
       Pick up that area of the screen using GET.
       Save the array as an OBJECT file.

     To check:
       Load in the new OBJECT file.
       Place it at another screen position using OBJECT.SHAPE.
       Check also that it can be PUT into any position.

    The uninitiated may well be wondering what the point of it all is.
    Why devise a method to load in an Object file if the brush file
    itself can be loaded in anyway?  It's a question of time. An IFF
    (brush) file loads in very slowly; an Object file much more
    quickly (see sample times below).

    Again I studied other sources for help with the hardest parts, and
    confess to borrowing certain patches of code from one or two
    programs on the Extras disk.  Byte by byte, I became more closely
    acquainted with the structures of IFF files and Object Files, but
    did not complete the process, and do not wish to repeat the
    experience.  But I got it all to work, including automatic setting
    of the screen depth to cope with different numbers of colours (up
    to 16 on a 640-wide screen).  It was important that data on image
    dimensions be obtainable not only from the IFF file for the
    conversion process itself, but also from the Object file, so that
    it is available as needed in other Basic programs, without the
    support of the data contained in the original IFF file.

    Knowing the screen depth, and thus how many colours an image may
    contain, is one thing.  Knowing what those colours are - the
    exact palette settings of the original image - is another matter.
    Now I may be wrong, but I do not think an Object file can contain
    that data.  You have to handle the colour settings separately,
    setting the palette accordingly in any program which uses an
    Object image.  The relatively painless method which I have adopted
    is to store the colour values in a temporary file in RAM: as soon
    as they are obtained from the IFF file.  A more permanent copy of
    that colours list can be made if needed, or it can be "merged"
    directly into any new Basic program which needs to use the
    information.

    All went astonishingly well as I created a variety of DPaint
    brushes, loaded them in, converted each one to an Object file, and
    then loaded that in.

    How big an image can it handle?  I haven't traced the limits, but
    get an error message if the image is too big.  The more colours
    there are, the smaller the maximum size of image.  But HiSoft has
    some really excellent features, including Meta-Commands which
    cause things to happen during the compilation. These commands take
    the form "REM $command argument".  For example, "REM $OPTION k40"
    changes the Heap size from the default 20k to 40k, and by this
    method I can easily increase the size of image the program can
    handle. (Something like the Basic CLEAR command, I suppose, though
    the documentation on that command never lives up to its name.)


    [32;41m    From HiSoft to AmigaBasic    [31;40m

    Once the HiSoft program was working as intended, I reasoned that
    there must be quite a few - a dozen? two or three? - MD readers
    who use DPaint and AmigaBasic, and who might find such a program
    useful.  All I had to do now was temporarily relinquish the joys
    of HiSoft Basic and join battle again with AmigaBasic.

    Obvious changes were easy, like changing the LIBRARY command from
    LIBRARY "hisoft.library" (actually it had been "extend.library",
    but we needn't go into that) to LIBRARY "dos.library":LIBRARY
    "graphics.library":LIBRARY "exec.library".

    After that, my troubles began, and despite anything the books say,
    I shall never again willingly use the AmigaBasic commands
    OBJECT.SHAPE or LOF(). You may recall that at the beginning of
    this document I mentioned that "Brush to Object" samples offered
    in books didn't work. I was back to that stage again, with Error 5
    (ILLEGAL FUNCTION CALL) and 62 (INPUT PAST END) appearing with
    tiresome regularity. It beats me how LOF can ever generate an Error
    62, since its sole reason for existence is to input as far as the
    end of a file AND NO FURTHER. How can it even think about
    "inputting past end"?  It exists to prevent that.

    I nearly gave up. I doubted everything. Might it be, for example,
    that the object files I was trying to load in using OBJECT.SHAPE
    were badly formatted? So I resorted to using Extras:ObjEdit (what
    a program!) to create object files which were surely formatted as
    such files should be.  But OBJECT.SHAPE still didn't like them.  I
    checked and double checked.  I did everything at least twice, once
    in HiSoft, and once in AmigaBasic. I used as many printed examples
    as I could find.  The same errors continued to appear in
    AmigaBasic, while HiSoft Basic performed beautifully at every
    stage.

    Enough of this tiresome raving.  What was to be done?

    I went back to sources - the Extras disk, and my earlier versions
    of "BrushToObject". There, I had not loaded in the Object file by
    using OBJECT.SHAPE or by anything like "Image$ = INPUT$(LOF(1),1)".
    Instead, I had read in the first few bytes of the file, one by
    one, in order to extract from the file itself details of image
    width, height, and depth.  Then I was able to calculate the size
    of the image array, and then I knew just how much data needed to
    be read in.

    Once I had worked out how to load the file without using
    OBJECT.SHAPE or LOF(), all was well.  I believe my new AmigaBasic
    program is immeasurably better than the version sent to Perth, and
    I also understand more about how the borrowed lines work.  I have
    put in a few hopefully useful comments to help interested readers
    find any of the patches they may wish to lift out for use in their
    own programs.  In particular, I have placed the "Load Object"
    subroutine at the end of the program, and have included there
    everything it needs to run as a separate program, so that it can
    be easily lifted out and used.

    That is, after all, the point of all this.


    [32;41m    Four sample brushes    [31;40m

    I explored and compared sizes and speeds with four brushes which
    were identical in size and line design, differing only in their
    number of colours.  They were within a rectangle measuring 100
    pixels left to right, 50 pixels top to bottom, and were named
    according to their number of colours. The sizes of the files
    produced and the AmigaBasic and HiSoft times of each process (in
    seconds) are shown below.  The time comparisons are misleading,
    since the HiSoft program uses OBJECT.SHAPE and LOF(), while, for
    reasons already explained, the AmigaBasic uses slower byte-by-byte
    methods, but the observed differences are typical of the relative
    speeds of the two languages.


                                  |
                Brush | Load time | Object | Save time | Load time
                file  | A/B   HS  | file   | A/B   HS  | A/B   HS
     -----------------|-----------|--------|-----------|-----------
     "two"       882  | 4.6  1.0  |  2252  | 3.5   1.4 | 2.3  <0.1
     "four"     1406  | 8.2  1.9  |  2252  | 3.5   3.9 | 2.3  <0.1
     "eight"    1914  |12.0  3.0  |  5220  | 7.7  10.0 | 3.3  0.1
     "sixteen"  2512  |20.6  8.5  | 11366  |17.0  44.0 | 4.8  0.3
                                  |

     The "Brush file: Load" and "Object file: Save" times occur only
     once, when a brush is converted to an Object.

     The "Object file: Load" times occur whenever Objects are used
     in another program.

     The "44.0" appears to be an anomaly. In this case, as described
     earlier, extra Heap space had to be allocated for the process,
     which may explain the delay.


    [32;41m    Choices and compromises    [31;40m

    So you can use ....

        OBJECT.SHAPE and/or LOF() in AmigaBasic (but I cannot
        get either of them to work reliably, if at all).

        OBJECT.SHAPE and/or LOF() in HiSoft. They work.

        Alternatives to OBJECT.SHAPE and/or LOF() in AmigaBasic.
        This is the method used in the BrushToObject program. It
        seems to be reasonably reliable, but is perhaps not as fast
        in its performance as we would like it to be.


    [32;41m    Known bugs    [31;40m

    Occasionally, one or two pixels of the new image appear in
    a colour other that that of the original. I don't know why.

    One column of pixels (the extreme left-hand column) is lost in
    the process, which only matters if you allow no safety margins
    around a brush when you originally save it. I haven't tried
    to correct this, since it doesn't seem very important.


    [32;41m    Practical details    [31;40m

    The easiest way to use the BrushToObject program is to make sure
    that AmigaBasic, the BrushToObject program, and the DPaint brush
    you wish to convert to an Object are all in the same drawer.  For
    speed, put all three of them into RAM: (or VDK: or VD0: or df0: or
    whatever you use).  Then just click on the program icon.

    Once the brush name has been entered, the brush appears line by
    line in the upper-left screen quarter, and subsequent progress -
    saving, reloading, etc.- is charted in a series of messages on
    consecutive lines in the upper-right quarter of the screen.

    When the new file is loaded, you are invited to click anywhere
    with the mouse, and a duplicate of the image appears at that spot.
    Your current directory will now hold an Object file called
    "(brushname).obj", ready for use by any other program.  Your RAM:
    directory will hold a file called "RGB" in which are listed all
    palette values needed to recreate the colours of the original
    brush.

    IFF files from sources other than DPaint should work.  I have,
    for example, grabbed IFF images from various places using "Snap"
    or "VSnap" (Fish Disk 326), and converted them to Object files.



[32m    ## 24 ## 24 ## 24 ## 24 ## 24 ## 24 ## 24 ## 24 ## 24 ## 24 ## 24 ##


