|
by Guy Cousineau
The GR command
places you in low resolution graphics mode. This mode is similar to
the graphics mode in APPLE BASIC and you can copy some of those
programs directly with only minor changes. In the GR mode, the
screen in partitioned into a 40 by 40 grid. Each grid can be any
colour which gives you reasonable block graphics capabilities. The COLOR command allows you to set the colour for the plot command. This is similar to choosing a pen colour before drawing something. The default colour is 0 and is always selected when you enter GR mode. Colour values may be set from 0 to 15 which should allow for 16 colours but it doesn't. In their efforts to make SMARTBASIC APPLE compatible, COLECO decided to add a translation table which converts the COLECO colours to APPLE colours. I have forgotten which colours cannot be accessed, but it is not important. You can defeat the colour translation with the following POKES:
POKE 18735,121:POKE 18736,0:POKE 18737,0:REM COLOR POKE 19256,0 :POKE 19257,0:POKE 19258,0:REM SCRN
Now you can use
the standard colours where 0 is transparent, 1 is black, and so on. The PLOT command will paint a block of the chosen COLOR at the x,y coordinates supplied. Say you want to show a single die with the number four. We need to plot four blocks in a square pattern:
100 GR 110 COLOR=7:REM choose a colour 120 PLOT 10,10 130 PLOT 10,12 140 PLOT 12,10 150 PLOT 12,12
Now we have the four dots, but what about drawing a box around them. I will almost certainly mess it up if I try to plot a whole bunch of points. That's where HLIN and VLIN come in handy. Both commands have a similar syntax and draw horizontal or vertical lines:
HLIN from,to AT line
Note that 'from' 'to' and 'line' can be integer values or variables. Back to the die program. Let's change the colour of the die outline and continue with:
160 COLOR=13:REM change colour for the border 170 HLIN 8,14 AT 8:REM a line 2 wider 2 above the die 180 HLIN 8,14 AT 14:REM same thing below the die 190 VLIN 8,14 AT 8:REM left side 200 VLIN 8,14 AT 14:REM right side
The SCRN command reads the colour of the selected grid position. This can be handy in a game situation where you want to know where OBSTACLES, WALLS, TREASURES, BAD GUYS, etc. are. Why bother keeping a separate matrix with all the positions of the players? Use the SCRN function:
a=SCRN(5,5)
This command assigns the COLOR value of grid position 5,5 to the variable a. This variable can now be checked against the known colours of walls, obstacles, other players, etc. Let's take a simple game in which we will use the joystick manipulation program illustrated in the previous article. We will start the program by drawing 10 OBSTACLES at random on the screen. The player will start in the upper left corner and will be allowed to move freely around the screen. If he should try to move on to an obstacle block the program will abort. Nothing fancy, but it illustrates the basic technique.
10 REM PDL and GR demo 20 GR 30 COLOR=12 40 x=0:y=0:REM set the start position 50 FOR z=1 TO 10 60 PLOT INT(RND(1)*30+5),INT(RND(1)*30+5):REM plot one random block 70 NEXT z 80 COLOR=7:REM set player colour 90 PLOT x,y:REM show where he is 100 x1=x:y1=y:REM remember where player was 110 p=PDL(5):REM read the joystick 120 y=y+(p=4 or p=6 or p=12)*(y<39) 130 y=y-(p=1 or p=3 or p=9)*(y>0) 140 x=x+(p=2 or p=3 or p=6)*(x<39) 150 x=x-(p>7)*(x>0) 160 IF SCRN(x,y)=12 GOTO 300:REM we hit one 170 COLOR=0:REM set colour to OFF 180 PLOT x1,y1:REM erase player at old position 200 GOTO 80:REM show new position and continue 299 REM hit an obstacle 300 PRINT chr$(7):REM wake player up 310 PRINT "You Lose" 320 END
As you can see
this is not a fancy program. There is no scoring and no timer. As a
matter of fact, the only way to end the program is by running into an
obstacle or pressing CONTROL-C. Note that the player is erased just
before being redrawn. This will create a short flash so you can see
where you are. If the player had been erased at line 95 when we
still knew where he was, he would have been OFF longer than ON and
would have been difficult to see. This is an important point to
consider in game animation: Make sure the bulk of the computer time
is used up while the player is ON. I have seen a few programs that save the contents of a GR screen. This seems like such a waste since it can be simply accomplished with the following:
10 DIM m(39,39) ...... 799 REM save game and exit 800 FOR x=0 TO 39 810 FOR y=0 TO 39 820 m(x,y)=SCRN(x,y) 830 NEXT y 840 NEXT x 850 REM save the x,y matrix to file or printer ... 899 REM reload the game 900 REM read the data from file .... 950 FOR x=0 TO 39 960 FOR y=0 to 39 970 COLOR=m(x,y) 980 PLOT x,y 990 NEXT y,x:REM remember this one?
TECHNICAL
NOTES
The screen in GR
mode is 256 by 160 pixels. Each of the GR blocks is 6 wide by 4 high
which gives 240 by 160. So if you were to paint the whole screen by
a series of HLIN or VLIN commands, there would be a BAR on the right
side which could not be painted. That is a minor problem as the bar
can be considered part of the border; see below for changing the
border colour.
The more
important point to consider is that the blocks are not square. In
order to plot a square block, you need 2 wide (2*6=12) by 3 high
(3*4=12). Using this technique, you can still create a 13x13 matrix
of square blocks which is reasonable for several GAME type
applications. Remember the colour-bleeding problem? The colour can only be specified for each section of 8 horizontal pixels. So why do a series of 6-pixel blocks not bleed when painted different colours? This is dues to a complicated algorithm that is used to paint part of the block on the foreground and part of the block on the background plane. I have not bothered entering into a detailed analysis of these plotting functions; interested hackers may analyze the PLOT routine to discover how it is done.
ROUTINE
ADDRESSES The GR command executes at 18492(483C). It sets the GR MODE flag, turns INVERSE off and resets the cursor and space values to high-bit characters. It then sets up the GR blocks with a series of character patterns of 6 bytes on and 2 bytes off. The GR text window is set to 4 lines at the bottom of the screen. Following are the POKE values required to change the window size:
number of lines18536(4868)18539(486B) 4320 5419 6518 7617 8716
The default
screen colour on initialization is set according to the value at
address 18633(48C9) which corresponds to 16*colorvalue. The
character colour is set according to the byte at 18711(4917) which
corresponds to 16*set colour+clear colour, similar to text colour.
The COLOR
command is parsed at 15926(3E36) and 14875(3A1B). The 2 routines
look for the symbol "=" and a numerical value respectively.
Since COLOR can be specified as a variable, it is not checked for
valid input. The routine executes at 11099(2B5B); if the value is 15
or less, the routine continues on to address 18735 where the colour
is translated and placed in memory. To disable the COLOR value
check, POKE 11107,255. Try plotting blocks with colours above 15 for
strange results.
PLOT is parsed
in several sections where the line is checked for a number, then
checked for a comma, then checked for a number. The CHECK FOR NUMBER
parser is at 14875(3A1B). It executes at 11139(2B83) where it first
checks that both coordinates are in the range of 0-39. It then jumps
to 19102(4A9E) where the type of block to plot is calculated.
HLIN is parsed
in 5 segments: number 14875(3A1B), comma 15939(3E43), number, 'AT'
15977(3E69), and number. The routine executes at 11170(2BA2) where
it checks that the FROM TO AT values are in the proper range. The
rest of the routine is located at 18805(4975); it sets up a loop to
call the PLOT routine for each element of the line.
VLIN is parsed
in an identical fashion to HLIN. It's execution is at 11219(2BD3)
and 18940(49FC). SCRN is a variable command and the parsing routine resides in an ambiguous part of memory like PEEK, TAB, SIN, etc. It's execution, however is in a fixed position at 11268(2C04). Since this is a MATH function, it gets the first coordinate from the Floating Point Accumulator, checks it for overflow and then gets the second coordinate from the token line. It then calls the translation routine at 19195(4AFB) and returns the COLOR value to the program via the Floating Point Accumulator. |