Автор: Mark C. Jones
Год: 1984
Издатели: Your Computer
Производитель: Your Computer
Языки:
Английский
Формат:
TZX лента
Требования:
ZX Spectrum 48K
Ссылки:
Страница на ZXArt
Страница на World Of Spectrum
Страница на Spectrum Computing
Скриншоты:
Год: 1984
Издатели: Your Computer
Производитель: Your Computer
Языки:
Формат:
Требования:
Ссылки:
Скриншоты:
3D Rotator
Mark Jones with a program which makes
his 3D rotator published in the July
1983 issue up to eight times faster.
In July of last year, I wrote a program for Your Computer
called 3D Rotator. This program allowed the Basic pro-
grammer to manipulate simply defined 3D figures at machine-
code speeds. A typical time was 0.5 seconds for a cube.
Though this was extremely fast relative to Basic it was not
fast enough for practical dynamic games. With this in mind
I have speeded up the 3D routine by as much as eight times
and made it more versatile. The speeds achieved now are as
fast as those seen in commercial games such as 3D Tank
Duel, with the advantage that they can be called from
Basic.
Data is stored as blocks of code at any memory location
that you specify. The data should be followed by a blank
area which = 12 * (number of sets of data). Therefore the
total memory required for any one image = 19 * (number of
sets of data). The data itself is made up of three 2's
complement numbers and one 1 byte number. A 2's complement
number is a 2 byte number where the negative form is 65536-
number, e.g., -5 = 65536-5 and +5 = 5. A 2 byte number is
Poked into memory as described on page 173 of the Spectrum
manual.
The numbers are stored as follows: x co-ordinate, y co-
ordinate, z co-ordinate and the 1 byte number 0 to indicate
a plot at x,y,z or 1 to draw a line from the last point
plotted to x,y,z. I include a Basic program - program A -
which will handle conversion of data into a suitable form
for the machine-code program. The Basic program will also
store the essential parameters such as the pointer to the
data, number of sets of data etc., for that figure.
Producing the data for a simple 3D figure is relatively
easy. I refer you for further information to my article
3D Rotator of July 1983 and Ian Angell's article BBC 3D
Graphics in the February 1984 edition of Your Computer.
[I do not have current access to these articles. The BBC
article would, naturally, not be linked from WoS, but
Mr. Jones' earlier one seems to be missing as well. In any
case, anyone with a passing knowledge of 3D Cartesian
co-ordinates should find the single example in the Basic
program sufficient.]
The 3D program allows the parameters for up to 16 3D
images. These parameters are stored in fixed areas from
65032 onwards and in blocks of 20 bytes. Thus the start of
the parameter area for figure 4 = 4*20 + 65032 - see
table 1 [at the end of this file].
Each 3D image stored in memory should have a separate set
of parameters though they might share a common set of data.
Draws need not point to a memory area after your 3D data
but I find I keep track of my memory state better by doing
so. For example, fig.0 and fig.1 might both be pyramids and
so use the same data. Draws for fig.0 is as normal, after
the data, but draws for fig.1 points at another section of
free memory and its ADDR points to the fig.0 data.
If it has all seemed rather complicated so far, do not
worry - it is really quite easy to use these 3D routines.
Here is an example:
To set up fig.0 as a cube first of all work out your data
and then store it in data statements in Basic program A.
For a cube there are 16 sets of data so adjust line 15
accordingly. The data is going to be stored at 40000 on-
wards so first of all ensure this area is free from the
Basic system with a
CLEAR 39999
and then adjust line 10 accordingly. Finally, this is going
to be figure 0 so adjust line 5. Now run program A.
Once the program is complete it will give you a print-out
of the next free memory available for data, 40316, and also
the position of the parameters area, 65032. If you now
wished to have another cube that could move independently
of fig.0 then simply make line 10 read
LET addr=40316
Line 5 should read
LET fig=1
and run the program again.
This is, of course, an example and actual addresses will
depend on the number of sets of data you use. Program A as
printed will set up fig.0 as a cube as in the above
example.
Now to actually produce a 3D image on the screen there
are a number of steps:
# Select the current figure by Poking 64976 with the
required figure number 0-15.
# RANDOMIZE USR 64234 actually converts your data to a list
of plots and draws stored in the figure's associated free
area of memory, pointed to by Draws.
# RANDOMIZE USR 64692 produces the 3D image on the screen
from the list of plots and draws.
# RANDOMIZE USR 64679 deletes the last image drawn by the
above routine.
Therefore using various sequences of these routines you can
produce 3D images from within your Basic programs. As an
added feature I have included a machine-code demonstration
program which will put the current figure indicated by
PEEK 64976
through its paces. The number of steps, and so speed of
this demonstration, can be altered by Poking 63501 with a
number between 1 and 150.
The routine is called with
RANDOMIZE USR 63500
Finally, to alter a given figure's position on the
screen, distance from you or angle simply alter the 2's
complement numbers PX, PY, PZ, Phi, Theta and Psi in the
parameters for that figure.
To run a demonstration of the routines from Basic load
with program A and then GO TO 5000. This sets up three
cubes, shows off the machine-code demonstration and then
leaves the three cubes to float around in space spinning.
If you remember the 3D Rotator routine in my last article
you may be interested to compare it with these new rou-
tines. The routine to handle the 3D conversion is written
more efficiently, uses 2 byte x,y,z co-ordinates and does
not draw the figure straight away. This allows a number of
figures to be produced in memory but not drawn until
needed.
This routine also handles calculations for lines parti-
ally off screen ensuring that the line eventually produced
for the draw routine does not go off screen.
The routines to draw and delete figures use a draw rou-
tine specially written for this program which is extremely
fast. The routine does not draw a line by plotting but by
manipulating screen addresses and rotating a mask.
To use the plot/draw routine for for yourself use the
following method:
# Set up an unused figure, e.g. fig. 15, by Poking both
DrawS and DrawP with the same value, the address of an
unused area of memory. Next Poke STFLG with 255.
# Store your plots and draws at this address in the
following form:
P,x,y where
P=0 to plot at x,y
P=1 to draw from the last point plotted to x,y
P=255 to end the data
x is a normal x co-ordinate
y has the range 0-191 where 0 is the bottom line of
the edit area.
e.g. to draw a frame around the screen the data would be:
0,0,0, 1,255,0, 1,255,191, 1,0,191, 1,0,0, 255
[ The last two paragraphs described how to enter the
programs. The result is on the TZX. Program A mentioned
above, with a few lines added to make it auto-load the
machine code, is called "Demo". The 3D Rotator machine
code itself is, of course, "3D Rotator". The final
program, "codereader", is the Basic program B used to
load the machine code into memory; it should not be
needed any more, but I've added it for completeness. ]
Table 1.
Offset Bytes Parameter Description Range
0 1 NUMB Number of sets of data 1-255
1 2 ADDR Start address of data
3 2 PX X co-ord (+ve left)
5 2 PY Y co-ord (+ve up)
7 2 PZ Z co-ord (+ve forward)
9 2 PHI Angle about X axis 0-359°
11 2 THETA Angle about Y axis 0-359°
13 2 PSI Angle about Z axis 0-359°
15 2 DRAWS Address of free memory
after 3D data
17 2 DRAWP 6*NUMB + DRAWS
19 1 STFLG Poke this with 0 the 0 to 255
first time you use
the 3D image
Mark Jones with a program which makes
his 3D rotator published in the July
1983 issue up to eight times faster.
In July of last year, I wrote a program for Your Computer
called 3D Rotator. This program allowed the Basic pro-
grammer to manipulate simply defined 3D figures at machine-
code speeds. A typical time was 0.5 seconds for a cube.
Though this was extremely fast relative to Basic it was not
fast enough for practical dynamic games. With this in mind
I have speeded up the 3D routine by as much as eight times
and made it more versatile. The speeds achieved now are as
fast as those seen in commercial games such as 3D Tank
Duel, with the advantage that they can be called from
Basic.
Data is stored as blocks of code at any memory location
that you specify. The data should be followed by a blank
area which = 12 * (number of sets of data). Therefore the
total memory required for any one image = 19 * (number of
sets of data). The data itself is made up of three 2's
complement numbers and one 1 byte number. A 2's complement
number is a 2 byte number where the negative form is 65536-
number, e.g., -5 = 65536-5 and +5 = 5. A 2 byte number is
Poked into memory as described on page 173 of the Spectrum
manual.
The numbers are stored as follows: x co-ordinate, y co-
ordinate, z co-ordinate and the 1 byte number 0 to indicate
a plot at x,y,z or 1 to draw a line from the last point
plotted to x,y,z. I include a Basic program - program A -
which will handle conversion of data into a suitable form
for the machine-code program. The Basic program will also
store the essential parameters such as the pointer to the
data, number of sets of data etc., for that figure.
Producing the data for a simple 3D figure is relatively
easy. I refer you for further information to my article
3D Rotator of July 1983 and Ian Angell's article BBC 3D
Graphics in the February 1984 edition of Your Computer.
[I do not have current access to these articles. The BBC
article would, naturally, not be linked from WoS, but
Mr. Jones' earlier one seems to be missing as well. In any
case, anyone with a passing knowledge of 3D Cartesian
co-ordinates should find the single example in the Basic
program sufficient.]
The 3D program allows the parameters for up to 16 3D
images. These parameters are stored in fixed areas from
65032 onwards and in blocks of 20 bytes. Thus the start of
the parameter area for figure 4 = 4*20 + 65032 - see
table 1 [at the end of this file].
Each 3D image stored in memory should have a separate set
of parameters though they might share a common set of data.
Draws need not point to a memory area after your 3D data
but I find I keep track of my memory state better by doing
so. For example, fig.0 and fig.1 might both be pyramids and
so use the same data. Draws for fig.0 is as normal, after
the data, but draws for fig.1 points at another section of
free memory and its ADDR points to the fig.0 data.
If it has all seemed rather complicated so far, do not
worry - it is really quite easy to use these 3D routines.
Here is an example:
To set up fig.0 as a cube first of all work out your data
and then store it in data statements in Basic program A.
For a cube there are 16 sets of data so adjust line 15
accordingly. The data is going to be stored at 40000 on-
wards so first of all ensure this area is free from the
Basic system with a
CLEAR 39999
and then adjust line 10 accordingly. Finally, this is going
to be figure 0 so adjust line 5. Now run program A.
Once the program is complete it will give you a print-out
of the next free memory available for data, 40316, and also
the position of the parameters area, 65032. If you now
wished to have another cube that could move independently
of fig.0 then simply make line 10 read
LET addr=40316
Line 5 should read
LET fig=1
and run the program again.
This is, of course, an example and actual addresses will
depend on the number of sets of data you use. Program A as
printed will set up fig.0 as a cube as in the above
example.
Now to actually produce a 3D image on the screen there
are a number of steps:
# Select the current figure by Poking 64976 with the
required figure number 0-15.
# RANDOMIZE USR 64234 actually converts your data to a list
of plots and draws stored in the figure's associated free
area of memory, pointed to by Draws.
# RANDOMIZE USR 64692 produces the 3D image on the screen
from the list of plots and draws.
# RANDOMIZE USR 64679 deletes the last image drawn by the
above routine.
Therefore using various sequences of these routines you can
produce 3D images from within your Basic programs. As an
added feature I have included a machine-code demonstration
program which will put the current figure indicated by
PEEK 64976
through its paces. The number of steps, and so speed of
this demonstration, can be altered by Poking 63501 with a
number between 1 and 150.
The routine is called with
RANDOMIZE USR 63500
Finally, to alter a given figure's position on the
screen, distance from you or angle simply alter the 2's
complement numbers PX, PY, PZ, Phi, Theta and Psi in the
parameters for that figure.
To run a demonstration of the routines from Basic load
with program A and then GO TO 5000. This sets up three
cubes, shows off the machine-code demonstration and then
leaves the three cubes to float around in space spinning.
If you remember the 3D Rotator routine in my last article
you may be interested to compare it with these new rou-
tines. The routine to handle the 3D conversion is written
more efficiently, uses 2 byte x,y,z co-ordinates and does
not draw the figure straight away. This allows a number of
figures to be produced in memory but not drawn until
needed.
This routine also handles calculations for lines parti-
ally off screen ensuring that the line eventually produced
for the draw routine does not go off screen.
The routines to draw and delete figures use a draw rou-
tine specially written for this program which is extremely
fast. The routine does not draw a line by plotting but by
manipulating screen addresses and rotating a mask.
To use the plot/draw routine for for yourself use the
following method:
# Set up an unused figure, e.g. fig. 15, by Poking both
DrawS and DrawP with the same value, the address of an
unused area of memory. Next Poke STFLG with 255.
# Store your plots and draws at this address in the
following form:
P,x,y where
P=0 to plot at x,y
P=1 to draw from the last point plotted to x,y
P=255 to end the data
x is a normal x co-ordinate
y has the range 0-191 where 0 is the bottom line of
the edit area.
e.g. to draw a frame around the screen the data would be:
0,0,0, 1,255,0, 1,255,191, 1,0,191, 1,0,0, 255
[ The last two paragraphs described how to enter the
programs. The result is on the TZX. Program A mentioned
above, with a few lines added to make it auto-load the
machine code, is called "Demo". The 3D Rotator machine
code itself is, of course, "3D Rotator". The final
program, "codereader", is the Basic program B used to
load the machine code into memory; it should not be
needed any more, but I've added it for completeness. ]
Table 1.
Offset Bytes Parameter Description Range
0 1 NUMB Number of sets of data 1-255
1 2 ADDR Start address of data
3 2 PX X co-ord (+ve left)
5 2 PY Y co-ord (+ve up)
7 2 PZ Z co-ord (+ve forward)
9 2 PHI Angle about X axis 0-359°
11 2 THETA Angle about Y axis 0-359°
13 2 PSI Angle about Z axis 0-359°
15 2 DRAWS Address of free memory
after 3D data
17 2 DRAWP 6*NUMB + DRAWS
19 1 STFLG Poke this with 0 the 0 to 255
first time you use
the 3D image