CPut version 1.1
November 13th 2000, Lennaert van der Linden (luckyone@xs4all.nl)

Contents :

        What it is
        Usage of routine
        Example
        Inner workings of the routine
        Credits
        Legal issues
        Bugs and quirks
        History

What it is :

        CPut is a replacement for the QBasic PUT command in screen mode
        13, that allows an image to be (partially or fully) offscreen.
        If an image fits on screen, the routine calls PUT to display it,
        if not, a new array is created, that contains the part of the
        image that does fit on screen and that new array is used with
        the PUT command to display to visible part of the image on screen.
        In other words, CPut does not give an error when the image is
        (partially) offscreen, like PUT does.

        The routine uses the MemCopy routine by Jonathan L. Leger, for
        performance.

        This is the updated version, which also allows to specify to
        which portion of the screen the image is clipped, as apposed to
        the full screen. An extra routine (see CPutRgn) is added to allow
        for this functionality. The original CPut routine still works the
        same.

Usage of routine :

        Is used basically the same as PUT. The syntax is a bit different,
        since QBasic does not support function overloading.

        Syntax :        CPUT x%, y%, sprite(), offset%, mode%

                x%, y%   - upperleft coordinates of sprite on screen

                sprite() - the array containing the image

                offset%  - the offset where the image can be found,
                           within the array. This value should be 0,
                           if you didn't use the offset with GET. the
                           offset can be used when multiple images are
                           stored in the array.

                mode%    - indicates how the image is displayed
                                0 - PSET
                                1 - PRESET
                                2 - AND
                                3 - OR
                                4 - XOR

        For more information, look up the PUT command in the QBasic Help.

        Before you use CPut, make sure your program contains both the CPut
        Sub and the MemCopy Sub.

        Added November 13th 2000 : CPutRgn

        CPutRgn allows you to specify to which portion of the screen the
        image is to be clipped, instead of the whole screen. It can be used
        for example for a playing field that only used part of the screen.

        Syntax :    CPutRgn x%, y%, sprite(), offset%, mode%, l%, t%, r%, b%

                    x%, y%      -   same as in CPut

                    sprite()    -   same as in CPut

                    offset%     -   same as in CPut

                    mode%       -   same as in CPut

                    l%, t%      -   topleft coordinate of screen to which
                                    the image is to be clipped

                    r%, b%      -   bottomright coordinate of screen to which
                                    the image is to be clipped

        Note : If the left coordinate is bigger than the right coordinate or
               the top coordinate is bigger than the bottom coordinate, the
               function exits without doing anything
Example :

        Included is a sample program (CPUTDEMO.BAS).

        It was written in QBasic v1.1. It should also work fine for other
        versions of QuickBasic (like version 4.5). You probably have to
        start QB with the /L option on the command line as such :

        QB /L

        When running the following keys are used :

            +       : Increase the size of the window
            -       : Decrease the size of the window
            *       : Place the window at a random place
            ESC     : End program

Inner workings of the routine :

        The variables that are used in a diagram :
        (sprite is the original sprite, newSprite is the
        newly created sprite).

                x,y *-----------*
                    |           |
                    |  sprite   |
                    |           |
                    |           |
                    |           |
                    *-----------* x1,y1
                    <--- ll ---->

              xo,yo *-----------*
                    |           |
                    | newSprite |
                    |           |
                    |           |
                    |           |
                    *-----------*
                    <--- ll2 --->

        newSprite as part of sprite :

                0,0 *--------------------------*
                    |                          |
                    |        sprite            |
                    |                          |
                    | lx,uy                    |
                    |    *-----------*         |
                    |    |           |         |
                    |    |           |         |
                    |    | newSprite |         |
                    |    |           |         |
                    |    |           |         |
                    |    *-----------*         |
                    |               rx,ly      |
                    |                          |
                    *--------------------------*

        The structure of a sprite (an array holding an image)
        in screen 13:

                el(0)   = x-size * 8
                el(1)   = y-size
                el(2..) = pixeldata

        Working of algorithm :
                First check if sprite is invisible.
                If so, exit routine.
                Check if fully visible. If so, use PUT with given sprite.
                Create new (smaller) sprite, copy visible part and use
                PUT with new sprite.

        The sprite is entirely invisible (does not have to be
        displayed), if :
                - x > screensize
                - y > screensize
                - x1 < 0
                - y1 < 0

        The sprite is entirely visible (we can use plain PUT), if :
                - x1 <= screensize
                - y1 <= screensize

        If sprite is not invisible or fully visible, the sprite is
        partially visible. Create the new sprite, copy the correct
        contents, calculate new upperleft corner (xo, yo) and use
        PUT.

        Update version 1.1 :

        CPut now calls CPutRgn, with the size of the screen (0,0 - 319,199)
        as parameters.
                
Credits

        Jonathan L. Leger for his MemCopy routine. The routine was
        part of one of the ABC-packets (located at
        www.basicguru.com/abc) and slightly adjusted, so it's con-
        tained in one Sub without the need of a global (SHARED) string.

Legal issues

        You may use this routine as you see fit, except sell it as is.
        If you do use it, I would appreciate it if you give me credit.

Bugs and quirks

        I haven't found any bugs up to now. Please notify me if you do.
        The routine has been tested on a AMD-K6 233Mhz, running under
        windows 98 with QBasic 1.1. It has not been tested on any other
        version of QBasic. If you do wish to use it with QB 4.5, make
        sure you use the /L option, when you start QB.

        Please e-mail me any comments and questions at : luckyone@xs4all.nl

History

        November 13th 2000
            Added CPutRgn routine
            Modified CPutDemo to use CPutRgn
            Added CPutSlim.BAS, a version of CPut that does not contain
            most of the remarks and is not indented, saving about 4k

        July 26th 1999
            Version 1.0
