How to Use Multidimensional Arrays with Graphics GET and PUT (72672)
The information in this article applies to:
- Microsoft QuickBASIC 4.0
- Microsoft QuickBASIC 4.0b
- Microsoft QuickBASIC 4.5
- Microsoft Basic Professional Development System (PDS) for MS-DOS and MS OS/2 7.0
- Microsoft Basic Professional Development System (PDS) for MS-DOS and MS OS/2 7.1
- Microsoft BASIC Compiler for MS-DOS and OS/2 6.0
- Microsoft BASIC Compiler for MS-DOS and OS/2 6.0b
This article was previously published under Q72672 SUMMARY
When using Basic's graphics GET and PUT statements and specifying the
index(es) of the array where you want to start storing the graphics
image, it is important to remember how the array is physically stored
in memory. If you fail to do so, each GET statement may actually
overwrite some of the information from the proceeding GET statement,
which can result in an "Illegal function call" on succeeding PUT
statements.
MORE INFORMATION
By default, Basic stores arrays in "column major order" in memory.
Column major order means that the array is stored in memory one column
at a time. For example, an array declared as
DIM x(1 to 2, 1 to 1)
will be stored in memory in the following order:
x(1,1) x(2,1) x(1,2) x(2,2)
Another option is to use the BC /R option to store arrays in row major
order. (Note: The QB.EXE or QBX.EXE environment does not have an
option for row major array order.) In row major order, the same array
above is stored in memory as follows:
x(1,1) x(1,2) x(2,1) x(2,2)
Basic's graphics GET statement copies video memory directly into the
array you specify (straight from video memory into the memory occupied
by the array). This can overwrite the existing array contents in a way
that you may not expect. The following example demonstrates a common
method of attempting to use graphics GET with a multidimensional
array, as well as the correct method:
DEFINT A-Z
CONST NUMIMAGES = 2
CONST IMAGESIZE = 100
DIM images(1 to NUMIMAGES, 1 to IMAGESIZE)
SCREEN 1
LINE (10,10)-(20,20),,BF
GET (10,10)-(20,20), images(1,1)
CLS
CIRCLE (15,15), 5
GET (10,10)-(20,20), images(2,1) ' Overwrites array from first GET
' when not using BC /R
The above program may appear to be the obvious approach to using a
multidimensional array to store several graphics images. The problem
with the above program is that the array is stored in column major
order, as follows:
_____ _____ _____ _____ _____ _____
| 1,1 | 2,1 | 1,2 | 2,2 | 1,3 | 2,3 | .......
----- ----- ----- ----- ----- -----
So the first GET statement above copies an image from video memory
straight into the array starting at element (1,1). Because GET
performs a direct copy into the array, element (2,1), (2,2), (2,3),
and so forth, are also used to hold the image. If we immediately PUT
the image starting at (1,1) back to the screen, it will appear
correctly.
The second GET statement in the example copies directly from video
memory into the array starting at element (2,1). This will actually
overwrite the first image starting at element (2,1) and continue
through the array. If we try to PUT images(2,1), the image will be
displayed correctly. If we try to PUT images(1,1), which has now been
overwritten, we will either see a corrupted image or receive an
"Illegal function call" error message.
There are two ways to avoid this behavior:
- Store arrays in row major order by using the /R option on the
BC.EXE compile line (this option is not available in the QB.EXE and
QBX.EXE environments).
-or-
- Change the way you use the array in your program to take the
array's physical storage into account. The following example
demonstrates how to change the above program to avoid overwriting
the images on successive GET statements:
DEFINT A-Z
CONST NUMIMAGES = 2
CONST IMAGESIZE = 100
DIM images(1 to IMAGESIZE, 1 to NUMIMAGES)
SCREEN 1
LINE (10,10)-(20,20),,BF
GET (10,10)-(20,20), images(1,1)
CLS
CIRCLE (15,15), 5
GET (10,10)-(20,20), images(1,2) ' Image stores OK when
' not using BC/R
In this example, separate images are stored in separate columns
of the array, rather than in separate rows. Because the array is
arranged by columns in memory, as follows,
_____ _____ _____ _____ _____ _____ _____ _____
| 1,1 | 2,1 | 3,1 |...|100,1| 1,2 | 2,2 | 3,2 |...|100,2|
----- ----- ----- ----- ----- ----- ----- -----
the images will not overwrite each other, and you can PUT both
images back to the screen correctly.
Modification Type: | Minor | Last Reviewed: | 8/16/2005 |
---|
Keywords: | KB72672 |
---|
|