"You owe everything an apology."
Marcy, addressing Al, "Married with Children"
YOUR SECOND GFA BASIC 3.XX MANUAL
- or -
HOW I LEARNED TO STOP WORRYING AND LOVE GFA-BASIC
PART 22
CHAPTER TWENTY - GRAPHICS (PART 2)
by Han Kempen
VQT_EXTENT
The function VQT_EXTENT can be used if you would like to draw a
rectangle around a text-string:
~VQT_EXTENT(txt$,x1,y1,x2,y2,x3,y3,x4,y4)
The coordinates of the four corners depend on the angle of the
text (0, 90, 180 or 270 degrees) and of course on the size of the
text. The point (x1,y1) is the lower left corner of the imaginary
rectangle around the text and the other points are arranged
anticlockwise around the text-string. Because the text rotates
around the TEXT-coordinates (start of the Base-Line), it will
take some trial and error to determine the correct position of
the rectangle if the angle is not 0 degrees. In the following
table you'll find the "true" origin of the rectangle, the width
and the height of the rectangle, and also the actual position of
the lower left corner of the text-block (x1,y1):
angle position (x1,y1) origin width height
0 lower left x1,y1 x2 y4
900 lower right x4,y4 x1 y3
1800 upper right x3,y3 x4 y2
2700 upper left x2,y2 x3 x4
The coordinates of the origin are (0,0), so with an angle of 0
degrees both x1 and y1 are 0. The rectangle rests on the x-axis,
while the left side coincides with the y-axis. This is a
"mathematical" y-axis, not a "screen" y-axis. This means you go
upwards for positive y-values. For an angle of 0 degrees the
coordinates will be:
(x4,y4). .(x3,y3)
. TEXTBLOCK .
(x1,y1) (x2,y2)
If you understand the table, you should be surprised by the
height 'x4' instead of 'y1' at an angle of 270 degrees. I think I
discovered a bug in GEM here. Correct GEM by changing the
following variables if an angle of 270 degrees is used:
y1=x4
SWAP x4,y4
Now, the height is 'y1' as you suspected. Clever, aren't we? I
have not been able to confirm my discovery. None of my reference-
books mention the bug. Perhaps it's not a bug, but my
imagination.
And then there is a terrible GFA-bug as well: in a compiled
program all coordinates are 0. Sigh. If you use the alternative
VQT_EXTENT-command you'll find the coordinates both in
interpreted and in compiled programs:
~VQT_EXTENT(txt$)
x1=PTSOUT(0)
y1=PTSOUT(1)
x2=PTSOUT(2)
(...)
y4=PTSOUT(7)
Line-A
The Line-A commands are faster than the corresponding VDI-
commands in GFA-Basic. Commands such as PSET, PTST and HLINE are
two to three times faster than the corresponding VDI-commands
PLOT, POINT and LINE. The difference should be even greater after
loading GDOS. The syntax of Line-A commands is more complicated,
but that's no problem for us GFA-experts. Line-A commands use the
SETCOLOR-index, not the VDI colour-index (see paragraph 'SETCOLOR
and VSETCOLOR' in this chapter). Because GFA uses Line-A commands
for sprites, you need a SETCOLOR-index for sprites as well (see
paragraph 'SPRITE')
Of course it's completely legal to use Line-A commands. Atari
has sworn an oath that you always will be able to use Line-A
commands. Until the world ends, or they change their mind. Atari
now recommends to avoid all the hardware-specific TOS-routines,
including Line-A commands. Remember their other promise, that the
BIOS system-variables (&H400 - &H4FF) are cast in concrete? Let
us pray they don't dump these variables in a lake. Amen.
HLINE
An additional advantage of the commands HLINE, ARECT and APOLY,
apart from the gain in speed, is that you don't have to change
the DEFFILL-parameters in the main program. For solid horizontal
lines, use:
pattern&=-1
adr%=V:pattern&
HLINE x1,y,x2,color,mode,adr%,0
You can't use &X1111111111111111 (16 bits) for the pattern,
because bit 15 of a word-variable is a flag for a negative
number. Yes, that's why the largest positive word is 2^15 - 1
(32767). The solution to this little problem is to assign -1 to
the word-variable. You have my word, now all 16 bits are 1. Use
BIN$ if you don't believe me. That's an insult, I gave you my 16
bits, didn't I?
For very complicated patterns you could use a word-array:
DIM pattern&(i)
adr%=V:pattern&(0)
(...) ! put fill-pattern in pattern&(0)
to pattern&(i)
HLINE x1,y,x2,color,mode,adr%,i
ACHAR and ATEXT
It's difficult to combine the Line-A commands ACHAR and ATEXT
with TEXT. The coordinates used with ACHAR and ATEXT determine
the position of the left upper corner of the (first) letter-box.
That's the Top-Line, not the Base-Line (see paragraph 'DEFTEXT').
With TEXT you can use GRAPHMODE, but you can't select a graphic
mode for ACHAR and ATEXT.
You can't use the text-style underlined (8) with ACHAR and
ATEXT. Probably a GFA-bug.
SGET and SPUT
A regular ST-screen (32,000 bytes in High, Medium or Low
resolution) fits in a string, but larger screens can not be
handled. SGET and SPUT are useless if the screen is larger
because a string can't contain more than 32767 bytes. TT-
programmers have to MALLOCate their own solution to this problem.
GET and PUT
You can save any rectangular part of the screen as a file:
GET x1,y1,x2,y2,pic$ ! a GET-picture
BSAVE file$,V:pic$,LEN(pic$) ! use the extension PUT in
the filename
Later, you could put the saved GET-picture back on the screen
with:
OPEN "I",#1,file$
LET bytes%=LOF(#1) ! how many bytes needed?
CLOSE #1
picture$=SPACE$(bytes%) ! reserve some space,
BLOAD file$,V:picture$ ! load the GET-picture
PUT x,y,picture$ ! careful: insensitive to CLIP-settings
Loading/saving several GET-pictures not only takes time, but it
also wastes a lot of valuable space on your disk. Each file
occupies at least 1 K, e.g. 10 small GET-rectangles occupy 10 K!
If you create an array of the GET-pictures you can save the
entire array in one file.
Loading a file is very boring for the user, so you should avoid
it if possible. You can avoid the loading of a GET-picture, but
you have to do some extra work. Don't start complaining, because
that's what you're paid for as a programmer. Transfer the GET-
picture to an INLINE-line in your program. If you then BMOVE the
picture to a string you can PUT the picture anywhere on the
screen. I'll assume you have a GET-picture in a file with a
length of 2000 bytes. After loading the file in an INLINE-line
you can use the following method:
INLINE picture%,2000
picture$=SPACE$(2000) ! create string for pic
BMOVE picture%,V:picture$,2000 ! put picture in string
PUT x,y,picture$ ! show the picture
A disadvantage of this method is that the picture is stored
twice in memory: in the INLINE-line and in the string. Why not
assign a string-variable to the picture in the INLINE-line?
Sounds easy, but it isn't. I'll assume you have the same 2000-
byte picture as a file. Add 10 to this length for the descriptor
(6 bytes) and backtrailer (4 bytes) of the string we are going to
create. Load the picture and run this:
INLINE picture%,2010
BMOVE picture%,picture%+6,2000 !# make room for descriptor
' Alternative method if the pic is available as GET-string pic$:
BMOVE V:pic$,picture%+6,2000 !# move pic from GET-string
LONG{picture%}=picture%+6 !# address of string
WORD{picture%+4}=LEN(pic$) !# string-length
LONG{picture%+LEN(pic$)+6}=picture% !# backtrailer
picture$="" ! create string-variable
ABSOLUTE picture$,picture% ! assign GET-pic to string
After this operation you can delete all lines marked with '#'.
The GET-picture is now immediately available in the program:
PUT x,y,picture$
A GET-string starts with two words for the x- and y-coordinate
of the lower right corner (relative to the upper left corner at
0,0) and one word for the number of bitplanes. The number of
bitplanes is determined by the resolution: 1 for High, 2 for
Medium and 4 for Low. The three-word header of a GET-string is
contructed as follows:
header$=MKI$(x)+MKI$(y)+MKI$(bitplanes)
These three words are followed by the actual picture as a list
of words. As the picture-width is not necessarily a multiple of
16, any bits beyond the right border will be ignored by the PUT-
command. These bits are not 0, there's random garbage beyond the
border. If you need a 'clean' GET-string for some special purpose
you could proceed as follows:
GET x1,y1,x2,y2,pic$ ! create GET-string
pic$=STRING$(LEN(pic$),0) ! clear the string
GET x1,y1,x2,y2,pic$ ! 'clean' GET-string
Here is the connection between GRAPHMODE and PUT-mode:
GRAPHMODE PUT-mode
1 (Replace) 3 (default)
2 (Transparent) 7
3 (Xor) 6
4 (Reverse Transparent) 13
In the paragraph 'GRAPHMODE' you have found a method to invert a
rectangular part of the screen with PBOX. Here is an alternative
method with GET/PUT:
GET x1,y1,x2,y2,block$
PUT x1,y1,block$,12 ! invert block
(...)
PUT x1,y1,block$,12 ! normal again
I have encountered a few programs in GFA-Basic 2.0 where PUT was
used just outside the screen (I know: bad, bad, bad). In GFA-
Basic 3.0 the program didn't work. The same occurred in a program
where a picture was BLOADed a few bytes before the screen-RAM. I
don't understand why GFA-Basic 3.0 doesn't accept this, as there
is some unused space there (read the paragraph 'RAM'), but I've
learned to correct this when I convert a program from GFA-Basic
2.0 to version 3.0.
Degas-Pictures
I declare Degas as the standard picture-format for GFA-Basic. A
Degas picture-file contains not only the actual picture (same
format as SGET-picture), but also the colour-palette of the
picture and the resolution. The original Degas-files have a
length of 32034 bytes:
1 word - resolution
16 words - palette
16000 words - picture data
You can check the resolution-word for the correct resolution (0
= Low, 1 = Medium, 2 = High), but you can also look at the
extension of the filename (PI1/PI2/PI3 for Low/Medium/High). In
the second Degas-version (Degas Elite), 16 words for colour-
animation can be added after the picture data. Files with colour-
animation have a length of 32066 bytes, but Degas Elite files
without colour-animation are exactly the same as the original
files.
A Degas Elite picture can (and really should!) be saved in a
compressed format. The extensions PC1/PC2/PC3 are used for
Low/Medium/High resolution. Also, the highest bit of the
resolution-word is set as a flag for a compressed picture. With
the proper unpack-routines you can show a compressed Degas-
picture reasonably fast on the screen.
If you have created a picture for one specific GFA-program, you
should put it in an INLINE-line. The GFA-program will become
larger, but the picture is immediately available in the program
and you can't lose the separate Degas-file. You shouldn't throw
the Degas-file away, just in case you accidentally corrupt the
INLINE-line. Assuming there is no colour-animation, you could
proceed as follows. Load the uncompressed Degas-picture in an
INLINE-line. Before you show the Degas-picture you change the
palette (don't forget to save the current palette first) and then
you BMOVE the picture to the monitor:
INLINE degas%,32034
~XBIOS(6,L:degas%+2) ! change palette
BMOVE degas%+34,XBIOS(2),32000 ! show pic on physical
screen
Other Picture-Formats
Although I declared Degas as the standard picture-format for
GFA-Basic, there are many other formats. GEM bitmap (.IMG),
Neochrome (.NEO), Tiny (.TN?) and Deluxe Paint(.IFF) are some
widely used picture-formats. Don't try to load all these formats
in your GFA-programs, but use a (Public Domain) program to
convert these pictures to Degas. Try to find conversion-programs
such as IFFCNV or PicSwitch. The GEM bitmap format is a serious
candidate for a standard format, but only for High resolution as
there is no standard method to include the palette in the IMG-
file.
BMOVE and RC_COPY
BMOVE can be used to move blocks of memory (e.g. complete
number-arrays, as described in the paragraph 'BMOVE' in chapter
4). It is the first choice if you are going to move a screen-wide
block of the physical or the logical screen (one or more
scanlines). In the paragraph 'Resolutions' you could already find
the length of a scanline in the three resolutions:
scanline
High resolution 80 bytes
Medium resolution 160 bytes
Low resolution 160 bytes
If the screen-block is narrower than the screen-width you have
to use the slower RC_COPY-command. And you can always use GET/PUT
if you don't mind the slower speed compared to BMOVE and RC_COPY.
With GET/PUT you are restricted to the logical screen, but with
BMOVE and RC_COPY you can use physical screen, logical screen
and/or a screen-buffer. In the following example the three
methods are used to move the first 16 scanlines of the logical
screen (High resolution) 16 scanlines down. The original
scanlines remain unaltered, so this actually is a copy-method:
GET 0,0,639,15,block$ ! upper 16 scanlines of
logical screen
PUT 0,16,block$,3 ! place block 16 scanlines down
'
RC_COPY XBIOS(3),0,0,640,16 TO XBIOS(3),0,16,3 ! faster
'
BMOVE XBIOS(3),XBIOS(3)+16*80,16*80 ! fastest
With a narrower block you can't use BMOVE:
GET 0,0,99,15,block$ ! block is 100 pixels wide
PUT 0,16,block$,3
'
RC_COPY XBIOS(3),0,0,100,16 TO XBIOS(3),0,16,3 ! fastest
VSYNC
The VSYNC-command is useful if you want to prevent irritating
blinking during animation. Always VSYNC before drawing a new
picture in an animation sequence (including SPRITE-animation).
The program is slowed down of course, because it waits for a
vertical blank interrupt before starting to draw. But it looks
much nicer.
BITBLT
BITBLT is supposed to be suitable for experienced professionals
only. Actually there are two BITBLT-commands available: one uses
VDI and the other Line-A.
The VDI BITBLT-command needs three integer-arrays with a lot of
parameters. Twenty-one parameters sounds frightening, but 14
parameters are more or less fixed, so you only have to think
about 7 parameters. That's 4 parameters for the source-rectangle
(x1,y1,x2,y2), 2 parameters for the destination-rectangle (x1,y1)
and 1 parameter for the copy-mode (same as PUT-mode). Sounds easy
now, doesn't it? Unfortunately this also means you can use BITBLT
for exactly the same operations as BMOVE and RC_COPY. All the
extra parameter-handling makes BITBLT even slower than BMOVE and
RC_COPY. You might as well forget the VDI BITBLT-command
completely. I don't understand why GFA calls this a VDI-command,
but you already forgot about this command, so I won't bother you
with that.
The Line-A BITBLT-command is a different cup of tea. Here you
need 22 parameters (preferably in one integer-array), but this is
reduced to about 9 parameters that really matter. This time the
command offers more possibilities than BMOVE or RC_COPY, but you
have to understand everything about scanlines and byte-offsets
first. If you do, you can use elements 10 and 16 of the integer-
array to do clever things. And you can use elements 18-21 to
create complicated fill-patterns. I'll leave that to the
professionals.
Both BITBLT-commands are insensitive to any (A)CLIPping and are
quite happy to blit bits everywhere in memory. So be careful and
expect your program to crash any time you test your thoroughly
debugged program.
ACLIP
Line-A commands are 'CLIP-sensitive', although they are not
supposed to be. Just in case you forgot you used some CLIP-
command somewhere else, you should always use an appropriate
ACLIP-command before a Line-A command. The following Line-A
commands are not influenced by ACLIP though: ALINE, HLINE, PSET,
PTST and BITBLT.
Blitter
The Blitter-TOS (1987) allows you to switch the Blitter on/off
from GFA-Basic with the function XBIOS 64 (Blitmode).
Procedures (CHAPTER.20)
Bitblt_a_screen_init \BITBLT_A\SCR_INIT
Bitblt_a BITBLT_A
Copy a rectangle to the physical screen:
@bitblt_a_screen_init(source.screen%)
@bitblt_a(100,100,150,150,0,0,3,80,80) ! for High res
In this case the box (100,100,150,150) from the source-screen
(usually an invisible second screen) is copied to position (0,0)
on the physical screen, using PUT-mode 3. For both source and
destination the 80 byte length of one scanline is used (for
Medium or Low resolution you need 160 bytes). Special effects are
possible by changing these offsets. Procedure Bitblt_a uses the
Line-A BITBLT-command.
Bitblt_get_init \BITBLT\GET_INIT
Bitblt_screen_init SCR_INIT
Bitblt BITBLT
Copy a rectangle to the physical screen:
@bitblt_screen_init(source.screen%)
@bitblt(100,100,150,150,0,0,3)
This has the same effect as the previous example, but it's
faster. Procedure Bitblt uses the VDI(?) BITBLT-command. It's
also possible to manipulate (a part of) a GET-string:
@bitblt_get_init(block$,destination.screen%,x2,y2)
@bitblt(50,50,x2,y2,0,0,3)
Here the rectangle (50,50,x2,y2) is copied from the GET-string
to (0,0) on the destination-screen. The GET-rectangle itself has
the coordinates (0,0,x2,y2).
Bitblt_ \BITBLT\SCROLL\
back_reverse,curtain,iris,merge_all
BACK_REV CURTAIN IRIS MERG_ALL
merge_leftright,merge_topdown MERG_LR MERG_TD
put_modes,random,roll_down PUT_MODE RANDOM ROLLDOWN
roll_downup,roll_right,roll_rightleft ROLLDNUP ROLL_R ROLL_RL
shrink,sliders,spiral4,vertical_blind
SHRINK SLIDERS SPIRAL4 V_BLIND
These are all scroll-Procedures that have to be used with
Procedures Bitblt_screen_init and Bitblt:
@bitblt_screen_init(invisible.screen%)
' Put a picture on the invisible (logical) screen
@bitblt_back_reverse ! uses Procedure Bitblt
Blend BLEND
Fade-over picture to the screen (several effects possible):
' Picture at address pic%
@blend(pic%,effect,delay) ! delay determines speed
Best results in High resolution.
Blitter BLITTER
Switch Blitter on or off (with Blitter-TOS only):
@blitter(TRUE) ! switch Blitter on
Box_dimmer BOX_DIM
Dim a box (e.g. to tell the user that an option is unavailable):
@box_dimmer(100,100,200,150) ! box greyed out
' Do something
@box_dimmer(100,100,200,150) ! normal again
Box_reverse BOX_REV
Invert box (e.g. to tell user that an option has been selected):
@box_reverse(100,100,200,150) ! box inverted
' Do something
@box_reverse(100,100,200,150) ! normal again
Busy BUSY
Fill the entire High resolution screen with bees and tell the
user that we're very busy right now:
@busy
Color_cycle and Cycle_every COLRCYCL
Cycle colours from VDI colour-index c1 to c2 every ticks (1/200
s):
@color_cycle(c1,c2,200,TRUE) ! cycle every second
' Do something else
@color_cycle(c1,c2,200,FALSE) ! switch cycling off
Colors_dim COLORDIM
Dim colours with VDI colour-index c1 to c2:
@colors_dim(c1,c2)
Cube CUBE
Draw a cube in High or Low resolution:
@cube(x,y,width,color,fill)
Degas_inline_med_low \DEGAS\INL_LOW
Show a Degas-picture (stored in an INLINE-line) in Low
resolution from a program running in Medium resolution:
@degas_inline_med_low(picture1%,0) ! waits for key/click
@degas_inline_med_low(picture2%,5) ! wait 5 seconds
Degas_inline_show \DEGAS\INL_SHOW
Show a Degas-picture that is stored in an INLINE-line:
@degas_inline_show(picture%)
A better idea than loading an uncompressed Degas-picture.
Degas_load \DEGAS\LOAD
Load a Degas-picture and the palette in strings:
@degas_load(file$,picture$,palet$,ok!)
IF ok!
' Degas-picture now available as SPUT-string picture$
ELSE
' Something went wrong
ENDIF
The Procedure loads both uncompressed and compressed Degas-
pictures. Colour-animation data are ignored.
Degas_load_show \DEGAS\LOADSHOW
Same as Degas_load, but now the Degas-picture is shown
immediately on the physical screen:
@degas_load_show(file$,ok!)
IF NOT ok!
' Something went wrong
ENDIF
Degas_save \DEGAS\SAVE
The logical screen is saved as an uncompressed Degas-picture:
@degas_save(file$,ok!)
Fill_border \FILL\FILLBORD
Fill an area within a coloured boundary:
@fill_border(100,100,red) ! stop FILLing at red
boundary
Fill_1_high_init and Fill_high_creation \FILL\FILL_HI
Create a Fill-pattern for High resolution:
@fill_1_high_init(pattern$) ! create Fill-pattern
DEFFILL ,pattern$ ! activate pattern
FILL 10,10 ! use pattern
Fill_1_low_init and Fill_low_creation \FILL\FILL_LOW
Create a Fill-pattern for Low resolution.
Fill_1_med_init and Fill_med_creation \FILL\FILL_MED
Create a Fill-pattern for Medium resolution.
Fill_init \FILL\FILLINIT
Load a Fill-pattern from an INLINE-line in a string:
@fill_init(adr%,pattern$)
Gem_image_load_show \PICTURE\IMG_SHOW
Show a GEM bitmap picture (*.IMG) on the screen:
@gem_image_load_show(file$,ok!) ! High resolution only
Line LINE
Let user draw a line on the screen and return the coordinates:
@line(x1,y1,x2,y2)
Magnify MAGNIFY
Put a magnified rectangular part of the TOS-screen somewhere
else on the screen:
@magnify(0,0,10,10,100,0,8) ! 8 times magnified
at (100,0)
Message MESSAGE
Show a centered message in reverse on the TOS-screen:
@message(" This is a message ",25,TRUE) ! on line 25
' Do something
@message("",25,FALSE) ! restore scrn
Message_any_key MESS_KEY
Show message "Press any key or mouse-button..." in reverse on
bottom line of TOS-screen and wait:
@message_any_key
Message_time MESS_TIM
Show message in reverse on bottom line of TOS-screen and wait:
@message_time("Read this",5) ! show for 5 seconds
Mirror MIRROR
Return mirror-image of a GET-string:
@mirror(source$,0,mirror$) ! vertical (1=horizontal)
Neochrome_load_show \PICTURE\NEO_SHOW
Show a Neochrome-picture on the monitor:
@neochrome_load_show(file$,ok!)
IF NOT ok!
' Something went wrong
ENDIF
Palet \PALET\PALET
Show current palette in a rectangle ('spectrum'):
@palet(100,100,10,10)
In this case the left upper corner of the rectangle is at
(100,100) and both height and width of each colour-box is 10
pixels.
Palet_low \PALET\PALETLOW
Install a new Low-palette:
@palet_low ! palette stored in
DATA-lines
Palet_medium \PALET\PALETMED
Install a new Medium-palette:
@palet_medium ! palette stored in
DATA-lines
Palet_save_int and Palet_change_int \PALET\PAL_INT
Save current palette in an integer-array and restore the saved
palette later:
@palet_save_int(palet%()) ! save palette
' Do something
@palet_change_int(palet%()) ! restore palette
Palet_save_str and Palet_change_str \PALET\PAL_STR
Save current palette in a (Degas-compatible) string and restore
the saved palette later:
@palet_save_str(palet$) ! save palette
' Do something
@palet_change_str(palet$) ! restore palette
Palet_string \PALET\PALSTRNG
Create a palette-string from DATA-lines:
RESTORE this.palet
@palet_string(palet$) ! make palette-string
@palet_change_str(palet$) ! activate the palette
Picture_init PICTURE
Prepare a picture on an invisible logical screen and return the
picture as a GET-string:
RESTORE picture.data
@picture_init(picture$) ! uses Screen2_init
& _restore
PUT 50,50,picture$
picture.data:
DATA BOX,0,0,80,80
DATA LINE 0,0,80,80
DATA END
This Procedure recognizes the following commands: DEFLINE,
DEFTEXT, LINE, DRAW, BOX, RBOX, TEXT and END (=last command)
Point POINT
Let user pick a point on the screen with the mouse:
@point("Click on point",x,y)
Rectangle \RECTNGLE\RECTNGLE
User cuts GET-rectangle from TOS-screen:
@rectangle(part$,x,y) ! left upper corner at (x,y)
CLS
PUT 0,0,part$
Rectangle_array_load \RECTNGLE\REC_AR_L
Load an array of GET-rectangles from disk:
@rectangle_array_load(file$,ok!,picture$())
IF ok!
PUT 10,10,picture$(0)
PUT 10,100,picture$(1)
ENDIF
Rectangle_array_save \RECTNGLE\REC_AR_S
Save an array of GET-rectangles on disk:
@rectangle_array_save(file$,picture$())
Rectangle_flash \RECTNGLE\REC_FLSH
Flash a rectangle several times (especially suitable for text-
boxes):
@rectangle_flash(50,50,200,150,5) ! flash 5 times
Rectangle_load \RECTNGLE\REC_LOAD
Load a GET-rectangle from disk:
@rectangle_load(file$,ok!,clip$)
IF ok!=TRUE
PUT 50,50,clip$
ENDIF
Rectangle_save \RECTNGLE\REC_SAVE
Save a GET-rectangle on disk:
@rectangle_save(file$,picture$)
Rectangle_shadow \RECTNGLE\REC_SHDW
Draw a rectangle with a shadow (3D-effect):
@rectangle_shadow(30,30,100,100)
Res_low_medium and Res_medium_low RESLOMED
Switch temporarily from Low to Medium resolution, e.g. to show
text:
@res_low_medium("000","770","700","007",palet$)
PRINT "This is a medium screen, shown from a program
running in Low!"
PRINT "In this example we use yellow letters on a black
screen."
~INP(2)
@res_medium_low(palet$) ! back to Low
(restore palette too)
Screen_cls_down \SCRN_CLS\DOWN
Clear screen by scrolling the screen downwards:
@screen_cls_down(2,black) ! steps of 2 scanlines;
make black
Screen_cls_luxaflex \SCRN_CLS\LUXAFLEX
Clear the screen with a luxaflex-effect:
@screen_cls_luxaflex
Screen_cls_scroll \SCRN_CLS\SCROLL
Clear the screen with an upwards scrolling rectangle in the
current foreground-colour (usually black):
@screen_cls_scroll
Screen_cls_shrink \SCRN_CLS\SHRINK
Clear the screen with a shrinking rectangle in the foreground-
colour (usually black):
@screen_cls_shrink
Screen_cls_up \SCRN_CLS\UP
As Screen_cls_down, but screen scrolls upwards.
Screen_convert \SCREEN\SCRNCONV
Convert picture on logical screen (from wrong resolution) to
current resolution (especially suitable to show a Medium or Low
picture in High):
' Load Medium picture in logical screen
@screen_convert(1) ! convert picture to High
Screen_dimmer \SCREEN\SCRN_DIM
Dim entire screen, e.g. to indicate that some time-consuming
action is going on):
@screen_dimmer(black,TRUE) ! use black colour
' Do something
@screen_dimmer(black,FALSE) ! restore screen
Screen_fill \SCREEN\SCRN_FIL
Fill High screen with a Fill-pattern:
@screen_fill(adr%)
Screen_invert \SCREEN\SCRN_INV
Invert entire High screen:
@screen_invert(TRUE) ! invert screen
' Do something
@screen_invert(FALSE) ! restore screen
Screen_shrink \SCREEN\SCRSHRNK
Shrink screen, e.g. to be able to show small copies of several
pictures together on one screen:
@screen_shrink(2,physbase%,physbase%,pic$) ! quarter size
Scroll_init \SCROLL\SCR_INIT
Scroll_cover,drop,luxaflex,middle COVER DROP LUXAFLEX MIDDLE
middlepush,random,rolldown,slider
MIDPUSH RANDOM ROLLDOWN SLIDER
spiral,strips,uncover,up,venetian
SPIRAL STRIPS UNCOVER UP VENETIAN
Scroll second screen on physical screen:
@scroll_init ! activate invisible second screen
' Put something nice on the invisible logical screen
@scroll_cover ! scroll down, covering current
monitor-picture
Scroll_text_down SCRLTXTD
Scroll text-lines one line down on the TOS-screen:
@scroll_text_down(1,5) ! scroll line 1 - 5 one
line down
This is much faster than rePRINTing lines 1 - 5 again one line
down.
Scroll_text_up SCRLTXTU
Scroll text-lines one line up on the TOS-screen:
@scroll_text_up(2,8) ! scroll line 2 - 8 one
line up
Spectrum_load_show ) \PICTURE\SPECSHOW
Put a Spectrum 512 picture on the screen:
@spectrum_load_show(file$,ok!) ! press a key to continue
Not all (old) ST's are able to show 512 colours.
Sprite_init_1 and Sprite_creation SPRITE
Create a sprite from DATA-lines:
@sprite_init_1(sprite1$)
Text_3d \TEXT\TEXT_3D
Create 3D-letters with TEXT:
@text_3d(10,10,"3D",black,26,0) ! size 26, angle 0
Text_at \TEXT\TEXT_AT
Same effect as PRINT AT(column,line), but uses TEXT:
@text_at(1,5,"Printed with TEXT at column 1, line 5")
You can use this Procedure to mix PRINTed text with TEXT-effects
such as bold, underlined, italics, etc.
Text_box \TEXT\TEXT_BOX
Put a text in a box:
@text_box(column,line,3,black,black,"Text in a box")
The start-position of the box is determined by column and line.
In this case the line-width of the box is 3 (if width is 0, a
double line is drawn) and black is used both for the box and the
text.
Text_box_center \TEXT\TEXT_CEN
Put a text in a centered box:
@text_box_center(3,black,black,"Text in a centered box")
Same as Procedure Text_box, but now the box appears in the
middle of the screen.
Text_box_invert \TEXT\TXET_BOX
Put inverted text (standard size) in a box:
@text_box_invert(x1,y1,x2,y2," Inverted text in a box ")
By the way, the filename is indeed TXET_BOX (inverted TEXT, get
it?)
Text_extent 5) \TEXT\TEXT_EXT
Return width and height of a TEXT-string:
TEXT 50,50,"Measure this text"
@text_extent("Measure this text",width,height)
You can now draw a rectangle around the text, although that's
not easy.
Text_parameters \TEXT\TEXT_PAR
Return current DEFTEXT-parameters:
@text_parameters(colour,attributes,angle,height)
Text_shadow \TEXT\TEXT_SHD
Create large letters (size 26) with shadow-effect:
@text_shadow(50,100," S H A D O W S ")
Textstyle_alert \TEXT\TEXTSTYL
Change text-style for ALERT (and FILESELECT):
@textstyle_alert(1)
ALERT 1,"A bold Alert-box",1,"OK",k
Tiny_load_show \PICTURE\TINYSHOW
Show a Tiny picture on the monitor:
@tiny_load_show(file$,ok!)
Too slow!
Functions (CHAPTER.20)
Digital$ DIGITAL
Return a number with 'LCD'-digits:
TEXT 50,100,@digital$("128")
Rgb_value$ RGB_VAL
Return RGB-string of a VDI colour-index:
PRINT "Background-colour is: &H";@rgb_value$(0)
PRINT "PRINT-colour is: &H";@rgb_value$(1)
Disclaimer
The text of the articles is identical to the originals like they appeared
in old ST NEWS issues. Please take into consideration that the author(s)
was (were) a lot younger and less responsible back then. So bad jokes,
bad English, youthful arrogance, insults, bravura, over-crediting and
tastelessness should be taken with at least a grain of salt. Any contact
and/or payment information, as well as deadlines/release dates of any
kind should be regarded as outdated. Due to the fact that these pages are
not actually contained in an Atari executable here, references to scroll
texts, featured demo screens and hidden articles may also be irrelevant.