5740 lines
236 KiB
Plaintext
5740 lines
236 KiB
Plaintext
|
Hello there.
|
|||
|
|
|||
|
My name is Denthor (Grant Smith) of the South African demo group ASPHYXIA.
|
|||
|
This is a trainer that have been writing on and off for the last few months
|
|||
|
in order to help out budding young graphics programmers. Currently there are
|
|||
|
nine tutorials in all, each with a text file and accompianing pascal source
|
|||
|
file. Also included are two or three "bonus" pascal files with various
|
|||
|
effects.
|
|||
|
|
|||
|
I have left the files in their origional form, so they contain some local
|
|||
|
stuff which you can ignore.
|
|||
|
|
|||
|
PLEASE LEAVE A RESPONSE! Any comments/criticisms/flames/suggestions etc are
|
|||
|
very welcome (I love getting mail!)
|
|||
|
|
|||
|
Leave all comments to smith9@batis.bis.und.ac.za
|
|||
|
|
|||
|
Hope to hear from you soon!
|
|||
|
|
|||
|
--
|
|||
|
DENTHOR, coder for ...
|
|||
|
_____ _____ ____ __ __ ___ ___ ___ ___ __ _____
|
|||
|
/ _ \ / ___> | _ \ | |_| | \ \/ / \ \/ / | | / _ \
|
|||
|
| _ | \___ \ | __/ | _ | \ / > < | | | _ |
|
|||
|
\_/ \_/ <_____/ |__| |__| |__| |__| /__/\__\ |__| \_/ \_/
|
|||
|
smith9@batis.bis.und.ac.za
|
|||
|
The great South African Demo Team! Contact us for info/code exchange!
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 1 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Hi there! This is Denthor of ASPHYXIA, AKA Grant Smith. This training
|
|||
|
program is aimed at all those budding young demo coders out there. I am
|
|||
|
assuming that the reader is fairly young, has a bit of basic Std. 6 math
|
|||
|
under his belt, has done a bit of programming before, probably in BASIC,
|
|||
|
and wants to learn how to write a demo all of his/her own.
|
|||
|
|
|||
|
This I what I am going to do. I am going to describe how certain routines
|
|||
|
work, and even give you working source code on how you do it. The source
|
|||
|
code will assume that you have a VGA card that can handle the
|
|||
|
320x200x256 mode. I will also assume that you have Turbo Pascal 6.0 or
|
|||
|
above (this is because some of the code will be in Assembly language,
|
|||
|
and Turbo Pascal 6.0 makes this incredibly easy to use). By the end of
|
|||
|
the first "run" of sections, you will be able to code some cool demo
|
|||
|
stuff all by yourself. The info you need, I will provide to you, but it
|
|||
|
will be you who decides on the most spectacular way to use it.
|
|||
|
|
|||
|
Why not download some of our demos and see what I'm trying to head you
|
|||
|
towards.
|
|||
|
|
|||
|
I will be posting one part a week on the Mailbox BBS. I have the first
|
|||
|
"run" of sections worked out, but if you want me to also do sections on
|
|||
|
other areas of coding, leave a message to Grant Smith in private E-Mail,
|
|||
|
or start a conversation here in this conference. I will do a bit of
|
|||
|
moderating of a sort, and point out things that have been done wrong.
|
|||
|
|
|||
|
In this, the first part, I will show you how you are supposed to set up
|
|||
|
your Pascal program, how to get into 320x200x256 graphics mode without a
|
|||
|
BGI file, and various methods of putpixels and a clearscreen utility.
|
|||
|
|
|||
|
NOTE : I drop source code all through my explanations. You needn't try
|
|||
|
to grab all of it from all over the place, at the end of each part I
|
|||
|
add a little program that uses all the new routines that we have
|
|||
|
learned. If you do not fully understand a section, leave me
|
|||
|
private mail telling me what you don't understand or asking how I
|
|||
|
got something etc, and I will try to make myself clearer. One
|
|||
|
last thing : When you spot a mistake I have made in one of my
|
|||
|
parts, leave me mail and I will correct it post-haste.
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Disclaimer
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Hi again, sorry that I have to add this, but here goes. All source code
|
|||
|
obtained from this series of instruction programs is used at your own
|
|||
|
risk. Denthor and the ASPHYXIA demo team hold no responsibility for any
|
|||
|
loss or damage suffered by anyone through the use of this code. Look
|
|||
|
guys, the code I'm going to give you has been used by us before in
|
|||
|
Demos, Applications etc, and we have never had any compliants of machine
|
|||
|
damage, but if something does go wrong with your computer, don't blame
|
|||
|
us. Sorry, but that's the way it is.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> The MCGA mode and how you get into it in Pascal without a BGI
|
|||
|
|
|||
|
|
|||
|
Lets face it. BGI's are next to worthless for demo coding. It is
|
|||
|
difficult to find something that is slower then the BGI units for doing
|
|||
|
graphics. Another thing is, they wern't really meant for 256 color
|
|||
|
screens anyhow. You have to obtain a specific external 256VGA BGI to get
|
|||
|
into it in Pascal, and it just doesn't make the grade.
|
|||
|
|
|||
|
So the question remains, how do we get into MCGA 320x200x256 mode in
|
|||
|
Pascal without a BGI? The answer is simple : Assembly language.
|
|||
|
Obviously assembly language has loads of functions to handle the VGA
|
|||
|
card, and this is just one of them. If you look in Norton Gides to
|
|||
|
Assembly Language, it says this ...
|
|||
|
|
|||
|
____________________________________________________________________
|
|||
|
INT 10h, 00h (0) Set Video Mode
|
|||
|
|
|||
|
Sets the video mode.
|
|||
|
|
|||
|
On entry: AH 00h
|
|||
|
AL Video mode
|
|||
|
|
|||
|
Returns: None
|
|||
|
|
|||
|
Registers destroyed: AX, SP, BP, SI, DI
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
This is all well and good, but what does it mean? It means that if you
|
|||
|
plug in the video mode into AL and call interrupt 10h, SHAZAM! you are
|
|||
|
in the mode of your choice. Now, the MCGA video mode is mode 13h, and
|
|||
|
here is how we do it in Pascal.
|
|||
|
|
|||
|
Procedure SetMCGA;
|
|||
|
BEGIN
|
|||
|
asm
|
|||
|
mov ax,0013h
|
|||
|
int 10h
|
|||
|
end;
|
|||
|
END;
|
|||
|
|
|||
|
There you have it! One call to that procedure, and BANG you are in
|
|||
|
320x200x256 mode. We can't actually do anything in it yet, so to go back
|
|||
|
to text mode, you make the video mode equal to 03h, as seen below :
|
|||
|
|
|||
|
Procedure SetText;
|
|||
|
BEGIN
|
|||
|
asm
|
|||
|
mov ax,0003h
|
|||
|
int 10h
|
|||
|
end;
|
|||
|
END;
|
|||
|
|
|||
|
|
|||
|
BANG! We are back in text mode! Now, cry all your enquiring minds, what
|
|||
|
use is this? We can get into the mode, but how do we actually SHOW
|
|||
|
something on the screen? For that, you must move onto the next section
|
|||
|
....
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Clearing the screen to a specific color
|
|||
|
|
|||
|
Now that we are in MCGA mode, how do we clear the screen. The answer is
|
|||
|
simple : you must just remember that the base adress of the screen is
|
|||
|
$a000. From $a000, the next 64000 bytes are what is actually displayed on
|
|||
|
the screen (Note : 320 * 200 = 64000). So to clear the screen, you just use
|
|||
|
the fillchar command (a basic Pascal command) like so :
|
|||
|
|
|||
|
FillChar (Mem [$a000:0],64000,Col);
|
|||
|
|
|||
|
What the mem command passes the Segment base and the Offset of a part of
|
|||
|
memory : in this case the screen base is the Segment, and we are starting
|
|||
|
at the top of the screen; Offset 0. The 64000 is the size of the screen
|
|||
|
(see above), and Col is a value between 0 and 255, which represents the
|
|||
|
color you want to clear the screen to.
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Putting a pixel on the screen (two different methoods)
|
|||
|
|
|||
|
If you look in Norton Guides about putting a pixel onto the screen, you
|
|||
|
will see this :
|
|||
|
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Writes a pixel dot of a specified color at a specified screen
|
|||
|
coordinate.
|
|||
|
|
|||
|
On entry: AH 0Ch
|
|||
|
AL Pixel color
|
|||
|
CX Horizontal position of pixel
|
|||
|
DX Vertical position of pixel
|
|||
|
BH Display page number (graphics modes with more
|
|||
|
than 1 page)
|
|||
|
|
|||
|
Returns: None
|
|||
|
|
|||
|
Registers destroyed: AX, SP, BP, SI, DI
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
As seen from our SetMCGA example, you would write this by doing the following:
|
|||
|
|
|||
|
Procedure INTPutpixel (X,Y : Integer; Col : Byte);
|
|||
|
BEGIN
|
|||
|
asm
|
|||
|
mov ah,0Ch
|
|||
|
mov al,[col]
|
|||
|
mov cx,[x]
|
|||
|
mov dx,[y]
|
|||
|
mov bx,[1]
|
|||
|
int 10h
|
|||
|
end;
|
|||
|
END;
|
|||
|
|
|||
|
The X would be the X-Coordinate, the Y would be the Y-Coordinate, and the Col
|
|||
|
would be the color of the pixel to place. Note that MCGA has 256 colors,
|
|||
|
numbered 0 to 255. The startoff pallette is pretty grotty, and I will show
|
|||
|
you how to alter it in my next lesson, but for now you will have to hunt for
|
|||
|
colors that fit in for what you want to do. Luckily, a byte is 0 to 255, so
|
|||
|
that is what we pass to the col variable. Have a look at the following.
|
|||
|
|
|||
|
CGA = 4 colours.
|
|||
|
4x4 = 16
|
|||
|
EGA = 16 colors.
|
|||
|
16x16 = 256
|
|||
|
VGA = 256 colors.
|
|||
|
Therefore an EGA is a CGA squared, and a VGA is an EGA squared ;-)
|
|||
|
|
|||
|
Anyway, back to reality. Even though the abouve procedure is written in
|
|||
|
assembly language, it is slooow. Why? I hear your enquiring minds cry. The
|
|||
|
reason is simple : It uses interrupts (It calls INT 10h). Interrupts are
|
|||
|
sloooow ... which is okay for getting into MCGA mode, but not for trying
|
|||
|
to put down a pixel lickety-split. So, why not try the following ...
|
|||
|
|
|||
|
Procedure MEMPutpixel (X,Y : Integer; Col : Byte);
|
|||
|
BEGIN
|
|||
|
Mem [VGA:X+(Y*320)]:=Col;
|
|||
|
END;
|
|||
|
|
|||
|
|
|||
|
The Mem command, as we have seen above, allows you to point at a certain
|
|||
|
point in memory ... the starting point is $a000, the base of the VGA's
|
|||
|
memory, and then we specify how far into this base memory we start.
|
|||
|
Think of the monitor this way. It starts in the top left hand corner at
|
|||
|
0. As you increase the number, you start to move across the screen to your
|
|||
|
right, until you reach 320. At 320, you have gone all the way across the
|
|||
|
screen and come back out the left side, one pixel down. This carries on
|
|||
|
until you reach 63999, at the bottom right hand side of the screen. This
|
|||
|
is how we get the equation X+(Y*320). For every increased Y, we must
|
|||
|
increment the number by 320. Once we are at the beginning of the Y line
|
|||
|
we want, we add our X by how far out we want to be. This gives us the
|
|||
|
exact point in memory that we want to be at, and then we set it equal to
|
|||
|
the pixel value we want.
|
|||
|
|
|||
|
The MEM methood of putpixel is much faster, and it is shown in the sample
|
|||
|
program at the end of this lesson. The ASPHYXIA team uses neither putpixel;
|
|||
|
we use a DMA-Straight-To-Screen-Kill-Yer-Momma-With-An-Axe type putipixel
|
|||
|
which is FAST. We will give it out, but only to those of you who show us
|
|||
|
you are serious about coding. If you do do anything, upload it to me,
|
|||
|
I will be very interested to see it. Remember : If you do glean anything
|
|||
|
from these training sessions, give us a mention in your demos and UPLOAD
|
|||
|
YOUR DEMO TO US!
|
|||
|
|
|||
|
Well, after this is the sample program; have fun with it, UNDERSTAND it,
|
|||
|
and next week I will start on fun with the pallette.
|
|||
|
|
|||
|
See you all later,
|
|||
|
- Denthor
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 2 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Hi there again! This is Grant Smith, AKA Denthor of ASPHYXIA. This is the
|
|||
|
second part of my Training Program for new programmers. I have only had a
|
|||
|
lukewarm response to my first part of the trainer series ... remember, if
|
|||
|
I don't hear from you, I will assume that you are all dead and will stop
|
|||
|
writing the series ;-). Also, if you do get in contact with me I will give
|
|||
|
you some of our fast assembly routines which will speed up your demos no
|
|||
|
end. So go on, leave mail to GRANT SMITH in the main section of the
|
|||
|
MailBox BBS, start up a discussion or ask a few questions in this Conference,
|
|||
|
leave mail to ASPHYXIA on the ASPHYXIA BBS, leave mail to Denthor on
|
|||
|
Connectix, or write to Grant Smith,
|
|||
|
P.O.Box 270
|
|||
|
Kloof
|
|||
|
3640
|
|||
|
See, there are many ways you can get in contact with me! Use one of them!
|
|||
|
|
|||
|
In this part, I will put the Pallette through it's paces. What the hell is
|
|||
|
a pallette? How do I find out what it is? How do I set it? How do I stop
|
|||
|
the "fuzz" that appears on the screen when I change the pallette? How do
|
|||
|
I black out the screen using the pallette? How do I fade in a screen?
|
|||
|
How do I fade out a screen? Why are telephone calls so expensive?
|
|||
|
Most of these quesions will be answered in this, the second part of my
|
|||
|
Trainer Series for Pascal.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> What is the Pallette?
|
|||
|
|
|||
|
A few weeks ago a friend of mine was playing a computer game. In the game
|
|||
|
there was a machine with stripes of blue running across it. When the
|
|||
|
machine was activated, while half of the the blue stripes stayed the same,
|
|||
|
the other half started to change color and glow. He asked me how two stripes
|
|||
|
of the same color suddenly become different like that. The answer is simple:
|
|||
|
the program was changing the pallette. As you know from Part 1, there are
|
|||
|
256 colors in MCGA mode, numbered 0 to 255. What you don't know is that each
|
|||
|
if those colors is made up of different intensities of Red, Green and Blue,
|
|||
|
the primary colors (you should have learned about the primary colors at
|
|||
|
school). These intensities are numbers between 0 and 63. The color of
|
|||
|
bright red would for example be obtained by setting red intensity to 63,
|
|||
|
green intensity to 0, and blue intensity to 0. This means that two colors
|
|||
|
can look exactly the same, eg you can set color 10 to bright red and color
|
|||
|
78 to color bright red. If you draw a picture using both of those colors,
|
|||
|
no-one will be able to tell the difference between the two.. It is only
|
|||
|
when you again change the pallette of either of them will they be able to
|
|||
|
tell the difference. Also, by changing the whole pallette, you can obtain
|
|||
|
the "Fade in" and "Fade out" effects found in many demos and games.
|
|||
|
Pallette manipulation can become quite confusing to some people, because
|
|||
|
colors that look the same are in fact totally seperate.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How do I read in the pallette value of a color?
|
|||
|
|
|||
|
This is very easy to do. To read in the pallette value, you enter in the
|
|||
|
number of the color you want into port $3c7, then read in the values of
|
|||
|
red, green and blue respectively from port $3c9. Simple, huh? Here is a
|
|||
|
procedure that does it for you :
|
|||
|
|
|||
|
Procedure GetPal(ColorNo : Byte; Var R,G,B : Byte);
|
|||
|
{ This reads the values of the Red, Green and Blue values of a certain
|
|||
|
color and returns them to you. }
|
|||
|
Begin
|
|||
|
Port[$3c7] := ColorNo;
|
|||
|
R := Port[$3c9];
|
|||
|
G := Port[$3c9];
|
|||
|
B := Port[$3c9];
|
|||
|
End;
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How do I set the pallette value of a color?
|
|||
|
|
|||
|
This is also as easy as 3.1415926535897932385. What you do is you enter in
|
|||
|
the number of the color you want to change into port $3c8, then enter the
|
|||
|
values of red, green and blue respectively into port $3c9. Because you are
|
|||
|
all so lazy I have written the procedure for you ;-)
|
|||
|
|
|||
|
|
|||
|
Procedure Pal(ColorNo : Byte; R,G,B : Byte);
|
|||
|
{ This sets the Red, Green and Blue values of a certain color }
|
|||
|
Begin
|
|||
|
Port[$3c8] := ColorNo;
|
|||
|
Port[$3c9] := R;
|
|||
|
Port[$3c9] := G;
|
|||
|
Port[$3c9] := B;
|
|||
|
End;
|
|||
|
|
|||
|
|
|||
|
Asphyxia doesn't use the above pallete procedures, we use assembler versions,
|
|||
|
which will be given to PEOPLE WHO RESPOND TO THIS TRAINER SERIES (HINT,
|
|||
|
HINT)
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How do I stop the "fuzz" that appears on my screen when I change the
|
|||
|
pallette?
|
|||
|
|
|||
|
If you have used the pallette before, you will have noticed that there is
|
|||
|
quite a bit of "fuzz" on the screen when you change it. The way we counter
|
|||
|
this is as follows : There is an elctron beam on your monitor that is
|
|||
|
constantly updating your screen from top to bottom. As it gets to the
|
|||
|
bottom of the screen, it takes a while for it to get back up to the top of
|
|||
|
the screen to start updating the screen again. The period where it moves
|
|||
|
from the bottom to the top is called the Verticle Retrace. During the
|
|||
|
verticle retrace you may change the pallette without affecting what is
|
|||
|
on the screen. What we do is that we wait until a verticle retrace has
|
|||
|
started by calling a certain procedure; this means that everything we do
|
|||
|
now will only be shown after the verticle retrace, so we can do all sorts
|
|||
|
of strange and unusual things to the screen during this retrace and only
|
|||
|
the results will be shown when the retrace is finished. This is way cool,
|
|||
|
as it means that when we change the pallette, the fuzz doesn't appear on
|
|||
|
the screen, only the result (the changed pallette), is seen after the
|
|||
|
retrace! Neat, huh? ;-) I have put the purely assembler WaitRetrace routine
|
|||
|
in the sample code that follows this message. Use it wisely, my son.
|
|||
|
|
|||
|
NOTE : WaitRetrace can be a great help to your coding ... code that fits
|
|||
|
into one retrace will mean that the demo will run at the same
|
|||
|
speed no matter what your computer speed (unless you are doing a lot
|
|||
|
during the WaitRetrace and the computer is slooooow). Note that in
|
|||
|
the following sample program and in our SilkyDemo, the thing will run
|
|||
|
at the same speed whether turbo is on or off.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How do I black out the screen using the pallette?
|
|||
|
|
|||
|
This is basic : just set the Red, Green and Blue values of all colors to
|
|||
|
zero intensity, like so :
|
|||
|
|
|||
|
Procedure Blackout;
|
|||
|
{ This procedure blackens the screen by setting the pallette values of
|
|||
|
all the colors to zero. }
|
|||
|
VAR loop1:integer;
|
|||
|
BEGIN
|
|||
|
WaitRetrace;
|
|||
|
For loop1:=0 to 255 do
|
|||
|
Pal (loop1,0,0,0);
|
|||
|
END;
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How do I fade in a screen?
|
|||
|
|
|||
|
Okay, this can be VERY effective. What you must first do is grab the
|
|||
|
pallette into a variable, like so :
|
|||
|
|
|||
|
VAR Pall := Array [0.255,1..3] of BYTE;
|
|||
|
|
|||
|
0 to 255 is for the 256 colors in MCGA mode, 1 to 3 is red, green and blue
|
|||
|
intensity values;
|
|||
|
|
|||
|
Procedure GrabPallette;
|
|||
|
VAR loop1:integer;
|
|||
|
BEGIN
|
|||
|
For loop1:=0 to 255 do
|
|||
|
Getpal (loop1,pall[loop1,1],pall[loop1,2],pall[loop1,3]);
|
|||
|
END;
|
|||
|
|
|||
|
This loads the entire pallette into variable pall. Then you must blackout
|
|||
|
the screen (see above), and draw what you want to screen without the
|
|||
|
construction being shown. Then what you do is go throgh the pallette. For
|
|||
|
each color, you see if the individual intensities are what they should be.
|
|||
|
If not, you increase them by one unit until they are. Beacuse intensites
|
|||
|
are in a range from 0 to 63, you only need do this a maximum of 64 times.
|
|||
|
|
|||
|
Procedure Fadeup;
|
|||
|
VAR loop1,loop2:integer;
|
|||
|
Tmp : Array [1..3] of byte;
|
|||
|
{ This is temporary storage for the values of a color }
|
|||
|
BEGIN
|
|||
|
For loop1:=1 to 64 do BEGIN
|
|||
|
{ A color value for Red, green or blue is 0 to 63, so this loop only
|
|||
|
need be executed a maximum of 64 times }
|
|||
|
WaitRetrace;
|
|||
|
For loop2:=0 to 255 do BEGIN
|
|||
|
Getpal (loop2,Tmp[1],Tmp[2],Tmp[3]);
|
|||
|
If Tmp[1]<Pall[loop2,1] then inc (Tmp[1]);
|
|||
|
If Tmp[2]<Pall[loop2,2] then inc (Tmp[2]);
|
|||
|
If Tmp[3]<Pall[loop2,3] then inc (Tmp[3]);
|
|||
|
{ If the Red, Green or Blue values of color loop2 are less then they
|
|||
|
should be, increase them by one. }
|
|||
|
Pal (loop2,Tmp[1],Tmp[2],Tmp[3]);
|
|||
|
{ Set the new, altered pallette color. }
|
|||
|
END;
|
|||
|
END;
|
|||
|
END;
|
|||
|
|
|||
|
Hey-presto! The screen fades up. You can just add in a delay before the
|
|||
|
waitretrace if you feel it is too fast. Cool, no?
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How do I fade out a screen?
|
|||
|
|
|||
|
This is just like the fade in of a screen, just in the opposite direction.
|
|||
|
What you do is you check each color intensity. If it is not yet zero, you
|
|||
|
decrease it by one until it is. BAAASIIIC!
|
|||
|
|
|||
|
Procedure FadeDown;
|
|||
|
VAR loop1,loop2:integer;
|
|||
|
Tmp : Array [1..3] of byte;
|
|||
|
{ This is temporary storage for the values of a color }
|
|||
|
BEGIN
|
|||
|
For loop1:=1 to 64 do BEGIN
|
|||
|
WaitRetrace;
|
|||
|
For loop2:=0 to 255 do BEGIN
|
|||
|
Getpal (loop2,Tmp[1],Tmp[2],Tmp[3]);
|
|||
|
If Tmp[1]>0 then dec (Tmp[1]);
|
|||
|
If Tmp[2]>0 then dec (Tmp[2]);
|
|||
|
If Tmp[3]>0 then dec (Tmp[3]);
|
|||
|
{ If the Red, Green or Blue values of color loop2 are not yet zero,
|
|||
|
then, decrease them by one. }
|
|||
|
Pal (loop2,Tmp[1],Tmp[2],Tmp[3]);
|
|||
|
{ Set the new, altered pallette color. }
|
|||
|
END;
|
|||
|
END;
|
|||
|
END;
|
|||
|
|
|||
|
Again, to slow the above down, put in a delay above the WaitRetrace. Fading
|
|||
|
out the screen looks SO much more impressive then just clearing the screen;
|
|||
|
it can make a world of difference in the impression your demo etc will
|
|||
|
leave on the people viewing it. To restore the pallette, just do this :
|
|||
|
|
|||
|
Procedure RestorePallette;
|
|||
|
VAR loop1:integer;
|
|||
|
BEGIN
|
|||
|
WaitRetrace;
|
|||
|
For loop1:=0 to 255 do
|
|||
|
pal (loop1,Pall[loop1,1],Pall[loop1,2],Pall[loop1,3]);
|
|||
|
END;
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
Well, there are most of those origional questions answered ;-) The following
|
|||
|
sample program is quite big, so it might take you a while to get around it.
|
|||
|
Persevere and thou shalt overcome. Pallette manipulation has been a thorn
|
|||
|
in many coders sides for quite some time, yet hopefully I have shown you
|
|||
|
all how amazingly simple it is once you have grasped the basics.
|
|||
|
|
|||
|
I need more feedback! In which direction would you like me to head? Is there
|
|||
|
any particular section you would like more info on? Also, upload me your
|
|||
|
demo's, however trivial they might seem. We really want to get in contact
|
|||
|
with/help out new and old coders alike, but you have to leave us that message
|
|||
|
telling us about yourself and what you have done or want to do.
|
|||
|
|
|||
|
IS THERE ANYBODY OUT THERE!?!
|
|||
|
|
|||
|
P.S. Our new demo should be out soon ... it is going to be GOOOD ... keep
|
|||
|
an eye out for it.
|
|||
|
|
|||
|
[ And so she came across him, slumped over his keyboard
|
|||
|
yet again . 'It's three in the morning' she whispered.
|
|||
|
'Let's get you to bed'. He stirred, his face bathed in
|
|||
|
the dull light of his monitor. He mutters something.
|
|||
|
As she leans across him to disconnect the power, she
|
|||
|
asks him; 'Was it worth it?'. His answer surprises her.
|
|||
|
'No.' he says. In his caffiene-enduced haze, he smiles.
|
|||
|
'But it sure is a great way to relax.' ]
|
|||
|
- Grant Smith
|
|||
|
Tue 13 July, 1993
|
|||
|
2:23 am.
|
|||
|
|
|||
|
See you next week!
|
|||
|
- Denthor
|
|||
|
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 3 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Greetings! This is the third part of the VGA Trainer series! Sorry it
|
|||
|
took so long to get out, but I had a running battle with the traffic
|
|||
|
department for three days to get my car registered, and then the MailBox
|
|||
|
went down. Ahh, well, life stinks. Anyway, today will do some things
|
|||
|
vital to most programs : Lines and circles.
|
|||
|
|
|||
|
Watch out for next week's part : Virtual screens. The easy way to
|
|||
|
eliminate flicker, "doubled sprites", and subjecting the user to watch
|
|||
|
you building your screen. Almost every ASPHYXIA demo has used a virtual
|
|||
|
screen (with the exception of the SilkyDemo), so this is one to watch out
|
|||
|
for. I will also show you how to put all of these loose procedures into
|
|||
|
units.
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith in private mail here on
|
|||
|
the Mailbox BBS.
|
|||
|
2) Write a message here in the Programming conference here
|
|||
|
on the Mailbox (Preferred if you have a general
|
|||
|
programming query or problem others would benefit from)
|
|||
|
3) Write to ASPHYXIA on the ASPHYXIA BBS.
|
|||
|
4) Write to Denthor, Eze or Livewire on Connectix.
|
|||
|
5) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
6) Call me (Grant Smith) at 73 2129 (leave a message if you
|
|||
|
call during varsity)
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Circle Algorithim
|
|||
|
|
|||
|
You all know what a circle looks like. But how do you draw one on the
|
|||
|
computer?
|
|||
|
|
|||
|
You probably know circles drawn with the degrees at these points :
|
|||
|
|
|||
|
0
|
|||
|
<20><>|<7C><>
|
|||
|
<20><><EFBFBD>|<7C><><EFBFBD>
|
|||
|
270 ----+---- 90
|
|||
|
<20><><EFBFBD>|<7C><><EFBFBD>
|
|||
|
<20><>|<7C><>
|
|||
|
180
|
|||
|
|
|||
|
Sorry about my ASCI ;-) ... anyway, Pascal doesn't work that way ... it
|
|||
|
works with radians instead of degrees. (You can convert radians to degrees,
|
|||
|
but I'm not going to go into that now. Note though that in pascal, the
|
|||
|
circle goes like this :
|
|||
|
|
|||
|
270
|
|||
|
<20><>|<7C><>
|
|||
|
<20><><EFBFBD>|<7C><><EFBFBD>
|
|||
|
180 ----+---- 0
|
|||
|
<20><><EFBFBD>|<7C><><EFBFBD>
|
|||
|
<20><>|<7C><>
|
|||
|
90
|
|||
|
|
|||
|
|
|||
|
Even so, we can still use the famous equations to draw our circle ...
|
|||
|
(You derive the following by using the theorem of our good friend
|
|||
|
Pythagoras)
|
|||
|
Sin (deg) = Y/R
|
|||
|
Cos (deg) = X/R
|
|||
|
(This is standard 8(?) maths ... if you haven't reached that level yet,
|
|||
|
take this to your dad, or if you get stuck leave me a message and I'll
|
|||
|
do a bit of basic Trig with you. I aim to please ;-))
|
|||
|
|
|||
|
Where Y = your Y-coord
|
|||
|
X = your X-coord
|
|||
|
R = your radius (the size of your circle)
|
|||
|
deg = the degree
|
|||
|
|
|||
|
To simplify matters, we rewrite the equation to get our X and Y values :
|
|||
|
|
|||
|
Y = R*Sin(deg)
|
|||
|
X = R*Cos(deg)
|
|||
|
|
|||
|
This obviousy is perfect for us, because it gives us our X and Y co-ords
|
|||
|
to put into our putpixel routine (see Part 1). Because the Sin and Cos
|
|||
|
functions return a Real value, we use a round function to transform it
|
|||
|
into an Integer.
|
|||
|
|
|||
|
Procedure Circle (oX,oY,rad:integer;Col:Byte);
|
|||
|
VAR deg:real;
|
|||
|
X,Y:integer;
|
|||
|
BEGIN
|
|||
|
deg:=0;
|
|||
|
repeat
|
|||
|
X:=round(rad*COS (deg));
|
|||
|
Y:=round(rad*sin (deg));
|
|||
|
putpixel (x+ox,y+oy,Col);
|
|||
|
deg:=deg+0.005;
|
|||
|
until (deg>6.4);
|
|||
|
END;
|
|||
|
|
|||
|
In the above example, the smaller the amount that deg is increased by,
|
|||
|
the closer the pixels in the circle will be, but the slower the procedure.
|
|||
|
0.005 seem to be best for the 320x200 screen. NOTE : ASPHYXIA does not use
|
|||
|
this particular circle algorithm, ours is in assembly language, but this
|
|||
|
one should be fast enough for most. If it isn't, give us the stuff you are
|
|||
|
using it for and we'll give you ours.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Line algorithms
|
|||
|
|
|||
|
There are many ways to draw a line on the computer. I will describe one
|
|||
|
and give you two. (The second one you can figure out for yourselves; it
|
|||
|
is based on the first one but is faster)
|
|||
|
|
|||
|
The first thing you need to do is pass what you want the line to look
|
|||
|
like to your line procedure. What I have done is said that x1,y1 is the
|
|||
|
first point on the screen, and x2,y2 is the second point. We also pass the
|
|||
|
color to the procedure. (Remember the screens top left hand corner is (0,0);
|
|||
|
see Part 1)
|
|||
|
|
|||
|
Ie. o (X1,Y1)
|
|||
|
ooooooooo
|
|||
|
ooooooooo
|
|||
|
oooooooo (X2,Y2)
|
|||
|
|
|||
|
Again, sorry about my drawings ;-)
|
|||
|
|
|||
|
To find the length of the line, we say the following :
|
|||
|
|
|||
|
XLength = ABS (x1-x2)
|
|||
|
YLength = ABS (y1-y2)
|
|||
|
|
|||
|
The ABS function means that whatever the result, it will give you an
|
|||
|
absolute, or posotive, answer. At this stage I set a variable stating
|
|||
|
wheter the difference between the two x's are negative, zero or posotive.
|
|||
|
(I do the same for the y's) If the difference is zero, I just use a loop
|
|||
|
keeping the two with the zero difference posotive, then exit.
|
|||
|
|
|||
|
If neither the x's or y's have a zero difference, I calculate the X and Y
|
|||
|
slopes, using the following two equations :
|
|||
|
|
|||
|
Xslope = Xlength / Ylength
|
|||
|
Yslope = Ylength / Xlength
|
|||
|
|
|||
|
As you can see, the slopes are real numbers.
|
|||
|
NOTE : XSlope = 1 / YSlope
|
|||
|
|
|||
|
Now, there are two ways of drawing the lines :
|
|||
|
|
|||
|
X = XSlope * Y
|
|||
|
Y = YSlope * X
|
|||
|
|
|||
|
The question is, which one to use? if you use the wrong one, your line
|
|||
|
will look like this :
|
|||
|
|
|||
|
o
|
|||
|
o
|
|||
|
o
|
|||
|
|
|||
|
Instead of this :
|
|||
|
|
|||
|
ooo
|
|||
|
ooo
|
|||
|
ooo
|
|||
|
|
|||
|
Well, the solution is as follows :
|
|||
|
|
|||
|
*\``|``/*
|
|||
|
***\|/***
|
|||
|
----+----
|
|||
|
***/|\***
|
|||
|
*/``|``\*
|
|||
|
|
|||
|
If the slope angle is in the area of the stars (*) then use the first
|
|||
|
equation, if it is in the other section (`) then use the second one.
|
|||
|
What you do is you calculate the variable on the left hand side by
|
|||
|
putting the variable on the right hand side in a loop and solving. Below
|
|||
|
is our finished line routine :
|
|||
|
|
|||
|
Procedure Line (x1,y1,x2,y2:integer;col:byte);
|
|||
|
VAR x,y,xlength,ylength,dx,dy:integer;
|
|||
|
xslope,yslope:real;
|
|||
|
BEGIN
|
|||
|
xlength:=abs (x1-x2);
|
|||
|
if (x1-x2)<0 then dx:=-1;
|
|||
|
if (x1-x2)=0 then dx:=0;
|
|||
|
if (x1-x2)>0 then dx:=+1;
|
|||
|
ylength:=abs (y1-y2);
|
|||
|
if (y1-y2)<0 then dy:=-1;
|
|||
|
if (y1-y2)=0 then dy:=0;
|
|||
|
if (y1-y2)>0 then dy:=+1;
|
|||
|
if (dy=0) then BEGIN
|
|||
|
if dx<0 then for x:=x1 to x2 do
|
|||
|
putpixel (x,y1,col);
|
|||
|
if dx>0 then for x:=x2 to x1 do
|
|||
|
putpixel (x,y1,col);
|
|||
|
exit;
|
|||
|
END;
|
|||
|
if (dx=0) then BEGIN
|
|||
|
if dy<0 then for y:=y1 to y2 do
|
|||
|
putpixel (x1,y,col);
|
|||
|
if dy>0 then for y:=y2 to y1 do
|
|||
|
putpixel (x1,y,col);
|
|||
|
exit;
|
|||
|
END;
|
|||
|
xslope:=xlength/ylength;
|
|||
|
yslope:=ylength/xlength;
|
|||
|
if (yslope/xslope<1) and (yslope/xslope>-1) then BEGIN
|
|||
|
if dx<0 then for x:=x1 to x2 do BEGIN
|
|||
|
y:= round (yslope*x);
|
|||
|
putpixel (x,y,col);
|
|||
|
END;
|
|||
|
if dx>0 then for x:=x2 to x1 do BEGIN
|
|||
|
y:= round (yslope*x);
|
|||
|
putpixel (x,y,col);
|
|||
|
END;
|
|||
|
END
|
|||
|
ELSE
|
|||
|
BEGIN
|
|||
|
if dy<0 then for y:=y1 to y2 do BEGIN
|
|||
|
x:= round (xslope*y);
|
|||
|
putpixel (x,y,col);
|
|||
|
END;
|
|||
|
if dy>0 then for y:=y2 to y1 do BEGIN
|
|||
|
x:= round (xslope*y);
|
|||
|
putpixel (x,y,col);
|
|||
|
END;
|
|||
|
END;
|
|||
|
END;
|
|||
|
|
|||
|
Quite big, isn't it? Here is a much shorter way of doing much the same
|
|||
|
thing :
|
|||
|
|
|||
|
function sgn(a:real):integer;
|
|||
|
begin
|
|||
|
if a>0 then sgn:=+1;
|
|||
|
if a<0 then sgn:=-1;
|
|||
|
if a=0 then sgn:=0;
|
|||
|
end;
|
|||
|
|
|||
|
procedure line(a,b,c,d,col:integer);
|
|||
|
var u,s,v,d1x,d1y,d2x,d2y,m,n:real;
|
|||
|
i:integer;
|
|||
|
begin
|
|||
|
u:= c - a;
|
|||
|
v:= d - b;
|
|||
|
d1x:= SGN(u);
|
|||
|
d1y:= SGN(v);
|
|||
|
d2x:= SGN(u);
|
|||
|
d2y:= 0;
|
|||
|
m:= ABS(u);
|
|||
|
n := ABS(v);
|
|||
|
IF NOT (M>N) then
|
|||
|
BEGIN
|
|||
|
d2x := 0 ;
|
|||
|
d2y := SGN(v);
|
|||
|
m := ABS(v);
|
|||
|
n := ABS(u);
|
|||
|
END;
|
|||
|
s := INT(m / 2);
|
|||
|
FOR i := 0 TO round(m) DO
|
|||
|
BEGIN
|
|||
|
putpixel(a,b,col);
|
|||
|
s := s + n;
|
|||
|
IF not (s<m) THEN
|
|||
|
BEGIN
|
|||
|
s := s - m;
|
|||
|
a:= a +round(d1x);
|
|||
|
b := b + round(d1y);
|
|||
|
END
|
|||
|
ELSE
|
|||
|
BEGIN
|
|||
|
a := a + round(d2x);
|
|||
|
b := b + round(d2y);
|
|||
|
END;
|
|||
|
end;
|
|||
|
END;
|
|||
|
|
|||
|
This routine is very fast, and should meet almost all of your requirements
|
|||
|
(ASPHYXIA used it for quite a while before we made our new one.)
|
|||
|
In the end program, both the new line routine and the circle routine are
|
|||
|
tested. A few of the procedures of the first parts are also used.
|
|||
|
|
|||
|
Line and circle routines may seem like fairly trivial things, but they are
|
|||
|
a vital component of many programs, and you may like to look up other
|
|||
|
methods of drawing them in books in the library (I know that here at the
|
|||
|
varsity they have books for doing this kind of stuff all over the place)
|
|||
|
A good line routine to look out for is the Bressenhams line routine ...
|
|||
|
there is a Bressenhams circle routine too ... I have documentaiton for them
|
|||
|
if anybody is interested, they are by far some of the fastest routines
|
|||
|
you will use.
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
Varsity has started again, so I am (shock) going to bed before three in
|
|||
|
the morning, so my quote this week wasn't written in the same wasted way
|
|||
|
my last weeks one was (For last week's one, I had gotten 8 hours sleep in
|
|||
|
3 days, and thought up and wrote the quote at 2:23 am before I fell asleep.)
|
|||
|
|
|||
|
[ "What does it do?" she asks.
|
|||
|
"It's a computer," he replies.
|
|||
|
"Yes, dear, but what does it do?"
|
|||
|
"It ..er.. computes! It's a computer."
|
|||
|
"What does it compute?"
|
|||
|
"What? Er? Um. Numbers! Yes, numbers!" He smiles
|
|||
|
worriedly.
|
|||
|
"Why?"
|
|||
|
"Why? Well ..um.. why?" He starts to sweat.
|
|||
|
"I mean, is it just something to dust around, or does
|
|||
|
it actually do something useful?"
|
|||
|
"Um...you can call other computers with it!" Hope lights
|
|||
|
up his eyes. "So you can get programs from other computers!"
|
|||
|
"I see. Tell me, what do these programs do?"
|
|||
|
"Do? I don't think I fol..."
|
|||
|
"I see. They compute. Numbers. For no particular reason." He
|
|||
|
withers under her gaze.
|
|||
|
"Yes, but..."
|
|||
|
She smiles, and he trails off, defeated. She takes another look
|
|||
|
at the thing. "Although," she says, with a strange look in
|
|||
|
her eyes. He looks up, an insane look of hope on his
|
|||
|
face. "Does it come in pink?" she asks.
|
|||
|
]
|
|||
|
- Grant Smith
|
|||
|
Tue 27 July, 1993
|
|||
|
9:35 pm.
|
|||
|
|
|||
|
See you next time,
|
|||
|
- Denthor
|
|||
|
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 4 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
|
|||
|
Howdy all! Welcome to the fourth part of this trainer series! It's a
|
|||
|
little late, but I am sure you will find that the wait was worth it,
|
|||
|
becase today I am going to show you how to use a very powerful tool :
|
|||
|
Virtual Screens.
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith in private mail here on
|
|||
|
the Mailbox BBS.
|
|||
|
2) Write a message here in the Programming conference here
|
|||
|
on the Mailbox (Preferred if you have a general
|
|||
|
programming query or problem others would benefit from)
|
|||
|
3) Write to ASPHYXIA on the ASPHYXIA BBS.
|
|||
|
4) Write to Denthor, Eze or Livewire on Connectix.
|
|||
|
5) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
6) Call me (Grant Smith) at 73 2129 (leave a message if you
|
|||
|
call during varsity)
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> What is a Virtual Screen and why do we need it?
|
|||
|
|
|||
|
Let us say you are generating a complex screen numerous times on the fly
|
|||
|
(for example scrolling up the screen then redrawing all the sprites for
|
|||
|
each frame of a game you are writing.) Do you have any idea how awful it
|
|||
|
would look if the user could actually see you erasing and redrawing each
|
|||
|
sprite for each frame? Can you visualise the flicker effect this would
|
|||
|
give off? Do you realise that there would be a "sprite doubling" effect
|
|||
|
(where you see two copies of the same sprite next to each other)? In the
|
|||
|
sample program I have included a part where I do not use virtual screens
|
|||
|
to demonstrate these problems. Virtual screens are not the only way to
|
|||
|
solve these problems, but they are definately the easiest to code in.
|
|||
|
|
|||
|
A virtual screen is this : a section of memory set aside that is exactly
|
|||
|
like the VGA screen on which you do all your working, then "flip" it
|
|||
|
on to your true screen. In EGA 640x350x16 you automatically have a
|
|||
|
virtual page, and it is possible to have up to four on the MCGA using a
|
|||
|
particular tweaked mode, but for our puposes we will set one up using base
|
|||
|
memory.
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Setting up a virtual screen
|
|||
|
|
|||
|
As you will have seen in the first part of this trainer series, the MCGA
|
|||
|
screen is 64000 bytes big (320x200=64000). You may also have noticed that
|
|||
|
in TP 6.0 you arn't allowed too much space for normal variables. For
|
|||
|
example, saying :
|
|||
|
|
|||
|
VAR Virtual : Array [1..64000] of byte;
|
|||
|
|
|||
|
would be a no-no, as you wouldn't have any space for your other variables.
|
|||
|
What is the solution? I hear you enquiring minds cry. The answer : pointers!
|
|||
|
Pointers to not use up the base 64k allocated to you by TP 6.0, it gets
|
|||
|
space from somewhere else in the base 640k memory of your computer. Here is
|
|||
|
how you set them up :
|
|||
|
|
|||
|
Type Virtual = Array [1..64000] of byte; { The size of our Virtual Screen }
|
|||
|
VirtPtr = ^Virtual; { Pointer to the virtual screen }
|
|||
|
|
|||
|
VAR Virscr : VirtPtr; { Our first Virtual screen }
|
|||
|
Vaddr : word; { The segment of our virtual screen}
|
|||
|
|
|||
|
If you put this in a program as it stands, and try to acess VirScr, your
|
|||
|
machine will probably crash. Why? Because you have to get the memory for
|
|||
|
your pointers before you can acess them! You do that as follows :
|
|||
|
|
|||
|
Procedure SetUpVirtual;
|
|||
|
BEGIN
|
|||
|
GetMem (VirScr,64000);
|
|||
|
vaddr := seg (virscr^);
|
|||
|
END;
|
|||
|
|
|||
|
This procedure has got the memory for the screen, then set vaddr to the
|
|||
|
screens segment. DON'T EVER LEAVE THIS PROCEDURE OUT OF YOUR PROGRAM!
|
|||
|
If you leave it out, when you write to your virtual screen you will probably
|
|||
|
be writing over DOS or some such thing. Not a good plan ;-).
|
|||
|
|
|||
|
When you have finished your program, you will want to free the memory
|
|||
|
taken up by the virtual screen by doing the following :
|
|||
|
|
|||
|
Procedure ShutDown;
|
|||
|
BEGIN
|
|||
|
FreeMem (VirScr,64000);
|
|||
|
END;
|
|||
|
|
|||
|
If you don't do this your other programs will have less memory to use for
|
|||
|
themselves.
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Putting a pixel to your virtual screen
|
|||
|
|
|||
|
This is very similar to putting a pixel to your normal MCGA screen, as
|
|||
|
discussed in part one... here is our origonal putpixel :
|
|||
|
|
|||
|
Procedure PutPixel (X,Y : Integer; Col : Byte);
|
|||
|
BEGIN
|
|||
|
Mem [VGA:X+(Y*320)]:=col;
|
|||
|
END;
|
|||
|
|
|||
|
For our virtual screen, we do the following :
|
|||
|
|
|||
|
Procedure VirtPutPixel (X,Y : Integer; Col : Byte);
|
|||
|
BEGIN
|
|||
|
Mem [Vaddr:X+(Y*320)]:=col;
|
|||
|
END;
|
|||
|
|
|||
|
It seems quite wasteful to have two procedures doing exactly the same thing,
|
|||
|
just to different screens, doesn't it? So why don't we combine the two like
|
|||
|
this :
|
|||
|
|
|||
|
Procedure PutPixel (X,Y : Integer; Col : Byte; Where : Word);
|
|||
|
BEGIN
|
|||
|
Mem [Where:X+(Y*320)]:=col;
|
|||
|
END;
|
|||
|
|
|||
|
To use this, you will say something like :
|
|||
|
|
|||
|
Putpixel (20,20,32,VGA);
|
|||
|
PutPixel (30,30,64,Vaddr);
|
|||
|
|
|||
|
These two statements draw two pixels ... one to the VGA screen and one to
|
|||
|
the virtual screen! Doesn't that make you jump with joy! ;-) You will
|
|||
|
have noticed that we still can't actually SEE the virtual screen, so on to
|
|||
|
the next part ...
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How to "Flip" your virtual screen on to the true screen
|
|||
|
|
|||
|
You in fact already have to tools to do this yourselves from information
|
|||
|
in the previous parts of this trainer series. We will of course use the
|
|||
|
Move command, like so :
|
|||
|
|
|||
|
Move (Virscr^,mem [VGA:0],64000);
|
|||
|
|
|||
|
simple, eh? Yuo may want to wait for a verticle retrace (Part 2) before you
|
|||
|
do that, as it may make the flip much smoother (and, alas, slower).
|
|||
|
|
|||
|
Note that most of our other procedures may be altered to support the
|
|||
|
virtual screen, such as Cls etc. (see Part 1 of this series), using the
|
|||
|
methoods described above (I have altered the CLS procedure in the sample
|
|||
|
program given at the end of this Part.)
|
|||
|
|
|||
|
We of ASPHYXIA have used virtual screens in almost all of our demos.
|
|||
|
Can you imagine how awful the SoftelDemo would have looked if you had to
|
|||
|
watch us redrawing the moving background, text and vectorballs for EACH
|
|||
|
FRAME? The flicker, doubling effects etc would have made it awful! So
|
|||
|
we used a virtual screen, and are very pleased with the result.
|
|||
|
Note, though, that to get the speed we needed to get the demo fast enough,
|
|||
|
we wrote our sprites routines, flip routines, pallette routines etc. all
|
|||
|
in assembly. The move command is very fast, but not as fast as ASM ;-)
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
I am writing this on the varsity computers in between lectures. I prefer
|
|||
|
writing & coding between 6pm and 4am, but it isn't a good plan when
|
|||
|
varsity is on ;-), so this is the first part of the trainer series ever
|
|||
|
written before 9pm.
|
|||
|
|
|||
|
I have been asked to do a part on scrolling the screen, so that is
|
|||
|
probably what I will do for next week. Also, ASPHYXIA will soon be putting
|
|||
|
up a small demo with source on the local boards. It will use routines
|
|||
|
that we have discussed in this series, and demonstrate how powerful these
|
|||
|
routines can be if used in the correct manner.
|
|||
|
|
|||
|
Some projects for you to do :
|
|||
|
1) Rewrite the flip statement so that you can say :
|
|||
|
flip (Vaddr,VGA);
|
|||
|
flip (VGA,Vaddr);
|
|||
|
( This is how ASPHYXIAS one works )
|
|||
|
|
|||
|
2) Put most of the routines (putpixel, cls, pal etc.) into a unit,
|
|||
|
so that you do not need to duplicate the procedures in each program
|
|||
|
you write. If you need help, leave me mail.
|
|||
|
|
|||
|
|
|||
|
See you next week
|
|||
|
- Denthor
|
|||
|
|
|||
|
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 5 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Hello! This is Denthor here with the 5 part of the ASPHYXIA VGA Trainer
|
|||
|
Series : The Scrolling Saga. I have had many requests for information on
|
|||
|
scrolling, so I decided to make it this weeks topic. Note that I do make
|
|||
|
reference to my recently released program TEXTER5, which should be available
|
|||
|
from wherever you get this message. (Note to Sysops : If you put the trainer
|
|||
|
series up on your boards, please add WORMIE.ZIP and TEXTER5.ZIP as they
|
|||
|
both suppliment this series)
|
|||
|
|
|||
|
By the way, sorry for the delay in the appearance of this part. Tests,
|
|||
|
projects and a few wild days of sin at the Wild Coast all conspired
|
|||
|
against the prompt appearance of this part. Also note I need more input as
|
|||
|
to what I should do future parts on, so leave me mail.
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith in private mail here on
|
|||
|
the Mailbox BBS.
|
|||
|
2) Write a message here in the Programming conference here
|
|||
|
on the Mailbox (Preferred if you have a general
|
|||
|
programming query or problem others would benefit from)
|
|||
|
3) Write to ASPHYXIA on the ASPHYXIA BBS.
|
|||
|
4) Write to Denthor, Eze or Livewire on Connectix.
|
|||
|
5) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
6) Call me (Grant Smith) at 73 2129 (leave a message if you
|
|||
|
call during varsity)
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> What is scrolling?
|
|||
|
|
|||
|
If you have ever seen a demo, you have probably seen some form of scrolling.
|
|||
|
Our SILKYDEMO has quite a nice example of scrolling. What it is is a long
|
|||
|
row of text moving across your screen, usually from right to left, eg :
|
|||
|
|
|||
|
H : Step 1
|
|||
|
He : Step 2
|
|||
|
Hel : Step 3
|
|||
|
Hell : Step 4
|
|||
|
Hello : Step 5
|
|||
|
Hello : Step 6
|
|||
|
|
|||
|
etc. etc. See the program attatched for an example of scrolling.
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> What do we scroll?
|
|||
|
|
|||
|
Usually, letters. Most groups put greetings and information in their
|
|||
|
'scrollies', as they are termed. You can also scroll and entire screen
|
|||
|
using the scrolling technique. Scrolling your text is a hell of a lot
|
|||
|
less boring then just having it appear on your screen. Unfortunately,
|
|||
|
'scrollies' have been used so many times in demos they are wearing a
|
|||
|
bit thin, so usually they are accompanied by a cool picture or some nice
|
|||
|
routine happening at the same time (In our SILKYDEMO we had a moving
|
|||
|
checkerboard and colour bars going at the same time).
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How do we scroll from side to side?
|
|||
|
|
|||
|
The theory behind scrolling is quite easy. Let us imagine that we are
|
|||
|
scrolling a 16x16 font grabbed by TEXTER (;-)) across the top of the
|
|||
|
screen (ie. 320 pixels) As we know, the VGA screen starts at zero at the
|
|||
|
top left hand part of the screen, then counts up to the right to 319, then
|
|||
|
goes back to the left hand side one pixel down at 320. (See Tut 1) This means
|
|||
|
that a 16*320 scroller takes up the space 0 to 5119 on the screen. In ascii
|
|||
|
this looks like this :
|
|||
|
|
|||
|
(0) . . (319)
|
|||
|
(320) . . (639)
|
|||
|
" " "
|
|||
|
(4800) . . (5119)
|
|||
|
|
|||
|
Simple enough. Now what we do is we put down the first Y-line of the first
|
|||
|
character onto the very right hand side of the screen , like so :
|
|||
|
|
|||
|
For loop1:=1 to 16 do
|
|||
|
Putpixel (319,loop1-1,font['A',1,loop1],vga);
|
|||
|
|
|||
|
This will draw some stuff on the very right hand side. Your screen should now
|
|||
|
look like this :
|
|||
|
|
|||
|
(0) . X. (319)
|
|||
|
(320) . X. (639)
|
|||
|
" " "
|
|||
|
(4800) . X. (5119)
|
|||
|
|
|||
|
Next, we move each line one to the left, ie :
|
|||
|
|
|||
|
For loop1:=0 to 15 do
|
|||
|
Move (mem[VGA:loop1*320+1],mem[VGA:loop1*320],320);
|
|||
|
|
|||
|
This scrolls the screen from right to left, which is the easiest to read.
|
|||
|
To scroll the screen from left to right, swap the +1 onto the other side
|
|||
|
of the command. Also, to increase the size of the portion scrolled, increase
|
|||
|
the 15 to however many lines from the top you wish to scroll-1.
|
|||
|
|
|||
|
After this move, your screen will look like this :
|
|||
|
|
|||
|
(0) . X . (319)
|
|||
|
(320) . X . (639)
|
|||
|
" " "
|
|||
|
(4800) . X . (5119)
|
|||
|
^
|
|||
|
Note this space
|
|||
|
|
|||
|
|
|||
|
What you then do is draw in the next line on the right hand side, move it,
|
|||
|
draw the next line, move it etc. etc. Tah-Dah! You have a scrolly! Fairly
|
|||
|
simple, isn't it?
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How do we scroll up or down?
|
|||
|
|
|||
|
To scroll up or down is also fairly simple. This can be used for 'movie
|
|||
|
credit' endings (I once wrote a little game with a desert scrolling down
|
|||
|
with you being a little robot on the bottom of the screen). The theory is
|
|||
|
this : Draw the top line (or bottom line) then move the entire screen :
|
|||
|
|
|||
|
Move (mem[vga:0],mem[vga:320],63680);
|
|||
|
{ 64000 - 320 = 63680 }
|
|||
|
|
|||
|
For scrolling down, or :
|
|||
|
|
|||
|
Move (mem[vga:320],mem[vga:0],63680);
|
|||
|
|
|||
|
For scrolling up. You then draw the next line and repeat.
|
|||
|
|
|||
|
Because of the simplicity of coding in a scrolly, most demos have one. It
|
|||
|
is usually best to have something extra happening on the screen so that
|
|||
|
the viewer doesn't get too bored, even, as I say, if it is only a really nice
|
|||
|
picture.
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
The University of Natal, Durban, Science Dept., now has 10 new 486's!
|
|||
|
This is a great boon, as now I can program nice routines during frees
|
|||
|
(even though I am a Commerce Student (Shhhhh) ;-) ). I can now use those
|
|||
|
previously wasted hours that I spent socialising and making friends
|
|||
|
coding instead ;-)
|
|||
|
|
|||
|
I suggest you get a copy of TEXTER, for coding demos with fonts, or in fact
|
|||
|
almost any graphics application, it is an amazing help, and we have used it
|
|||
|
for *ALL* our demos. (P.S. We have written many demos, but many have been
|
|||
|
written for companies and have not been released for the general public)
|
|||
|
NOTE : For TEXTER's test program TEST.PAS, add {$X+} {$R-} if you have range
|
|||
|
checking on (I code with it off.)
|
|||
|
|
|||
|
[ "I'm from the Computer Inspection Agency, sir,
|
|||
|
I'm here to check your computer. Here is
|
|||
|
my identification."
|
|||
|
"Certainly. Have a look, I'm clean. I don't have
|
|||
|
any pirated software."
|
|||
|
The C-man pushes past him and sits in front of the
|
|||
|
computer. He notes the fact that the computer
|
|||
|
is currently off with a look of disdain. He
|
|||
|
makes a note on his clipboard. He boots up.
|
|||
|
"What is this?" he asks, pointing at the screen.
|
|||
|
"It's MasterMenu" stutters the man. "I wrote it
|
|||
|
myself!"
|
|||
|
"Do you know what the penalty is for using junk
|
|||
|
like this on a private machine?" The C-man smiles.
|
|||
|
"This is a two-month sentance in itself!"
|
|||
|
"I'm sorry sir! It won't happen again!"
|
|||
|
"I know. I'll make sure of that." He smiles again.
|
|||
|
The C-man runs through the hard drive, checking for
|
|||
|
illeagal software, bad programs and anti-government
|
|||
|
propaganda. He notes with satisfaction that he has
|
|||
|
enough to put this weenie away for ten years, not that
|
|||
|
it mattered. He usually could just make something up.
|
|||
|
He comes to the last entry on the aphebetised menu tree.
|
|||
|
His hands jerk away from the keyboard. Then, tentatively,
|
|||
|
he types in the three letters of doom. He looks at the
|
|||
|
man, who is backing away with wide eyes and his hands
|
|||
|
outstretched in front of him, as if to ward off a blow.
|
|||
|
The C-man smiles, his lips a thin, hard line.
|
|||
|
"Windows!"
|
|||
|
]
|
|||
|
- Grant Smith
|
|||
|
1:55pm
|
|||
|
16/9/93
|
|||
|
|
|||
|
Cheers,
|
|||
|
- Denthor
|
|||
|
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 6 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Hi there! I'm back, with the latest part in the series : Pregenerated
|
|||
|
arrays. This is a fairly simple concept that can treble the speed of
|
|||
|
your code, so have a look.
|
|||
|
|
|||
|
I still suggest that if you haven't got a copy of TEXTER that you get it.
|
|||
|
This is shareware, written by me, that allows you to grab fonts and use
|
|||
|
them in your own programs.
|
|||
|
|
|||
|
I downloaded the Friendly City BBS Demo, an intro for a PE BBS, written
|
|||
|
by a new group called DamnRite, with coder Brett Step. The music was
|
|||
|
excellent, written by Kon Wilms (If I'm not mistaken, he is an Amiga
|
|||
|
weenie ;-)). A very nice first production, and I can't wait to see more
|
|||
|
of their work. I will try con a local BBS to allow me to send Brett some
|
|||
|
fido-mail.
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith in private mail here on
|
|||
|
the Mailbox BBS.
|
|||
|
2) Write a message here in the Programming conference here
|
|||
|
on the Mailbox (Preferred if you have a general
|
|||
|
programming query or problem others would benefit from)
|
|||
|
3) Write to ASPHYXIA on the ASPHYXIA BBS.
|
|||
|
4) Write to Denthor, Eze or Livewire on Connectix.
|
|||
|
5) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
6) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
|
|||
|
call during varsity)
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Why do I need a lookup table? What is it?
|
|||
|
|
|||
|
A lookup table is an imaginary table in memory where you look up the
|
|||
|
answers to certain mathematical equations instead of recalculating them
|
|||
|
each time. This may speed things up considerably. Please note that a
|
|||
|
lookup table is sometimes referred to as a pregenerated array.
|
|||
|
|
|||
|
One way of looking at a lookup table is as follows : Let us say that for
|
|||
|
some obscure reason you need to calculate a lot of multiplications (eg.
|
|||
|
5*5 , 7*4 , 9*2 etc.). Instead of actually doing a slow multiply each
|
|||
|
time, you can generate a kind of bonds table, as seen below :
|
|||
|
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
|
|||
|
<EFBFBD><EFBFBD><EFBFBD>Ķ 1 <20> 2 <20> 3 <20> 4 <20> 5 <20> 6 <20> 7 <20> 8 <20> 9 <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵
|
|||
|
<EFBFBD> 1 <20> 1 <20> 2 <20> 3 <20> 4 <20> 5 <20> 6 <20> 7 <20> 8 <20> 9 <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ
|
|||
|
<EFBFBD> 2 <20> 2 <20> 4 <20> 6 <20> 8 <20> 10 <20> 12 <20> 14 <20> 16 <20> 18 <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ
|
|||
|
<EFBFBD> 3 <20> 3 <20> 6 <20> 9 <20> 12 <20> 15 <20> 18 <20> 21 <20> 24 <20> 27 <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ
|
|||
|
<EFBFBD> 4 <20> 4 <20> 8 <20> 12 <20> 16 <20> 20 <20> 24 <20> 28 <20> 32 <20> 36 <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ
|
|||
|
<EFBFBD> 5 <20> 5 <20> 10 <20> 15 <20> 20 <20> 25 <20> 30 <20> 35 <20> 40 <20> 45 <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ
|
|||
|
<EFBFBD> 6 <20> 6 <20> 12 <20> 18 <20> 24 <20> 30 <20> 36 <20> 42 <20> 48 <20> 54 <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ
|
|||
|
<EFBFBD> 7 <20> 7 <20> 14 <20> 21 <20> 28 <20> 35 <20> 42 <20> 49 <20> 56 <20> 63 <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ
|
|||
|
<EFBFBD> 8 <20> 8 <20> 16 <20> 24 <20> 32 <20> 40 <20> 48 <20> 56 <20> 64 <20> 72 <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ
|
|||
|
<EFBFBD> 9 <20> 9 <20> 18 <20> 27 <20> 36 <20> 45 <20> 54 <20> 63 <20> 72 <20> 81 <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
This means that instead of calculating 9*4, you just find the 9 on the
|
|||
|
top and the 4 on the side, and the resulting number is the answer. This
|
|||
|
type of table is very useful when the equations are very long to do.
|
|||
|
|
|||
|
The example I am going to use for this part is that of circles. Cast
|
|||
|
your minds back to Part 3 on lines and circles. The circle section took
|
|||
|
quite a while to finish drawing, mainly because I had to calculate the
|
|||
|
SIN and COS for EVERY SINGLE POINT. Calculating SIN and COS is obviously
|
|||
|
very slow, and that was reflected in the speed of the section.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How do I generate a lookup table?
|
|||
|
|
|||
|
This is very simple. In my example, I am drawing a circle. A circle has
|
|||
|
360 degrees, but for greater accuracy, to draw my circle I will start
|
|||
|
with zero and increase my degrees by 0.4. This means that in each circle
|
|||
|
there need to be 8000 SINs and COSes (360/0.4=8000). Putting these into
|
|||
|
the base 64k that Pascal allocates for normal variables is obviously not
|
|||
|
a happening thing, so we define them as pointers in the following
|
|||
|
manner:
|
|||
|
TYPE table = Array [1..8000] of real;
|
|||
|
|
|||
|
VAR sintbl : ^table;
|
|||
|
costbl : ^table;
|
|||
|
|
|||
|
Then in the program we get the memory for these two pointers. Asphyxia
|
|||
|
was originally thinking of calling itself Creative Reboot Inc., mainly
|
|||
|
because we always forgot to get the necessary memory for our pointers.
|
|||
|
(Though a bit of creative assembly coding also contributed to this. We
|
|||
|
wound up rating our reboots on a scale of 1 to 10 ;-)). The next obvious
|
|||
|
step is to place our necessary answers into our lookup tables. This can
|
|||
|
take a bit of time, so in a demo, you would do it in the very beginning
|
|||
|
(people just think it's slow disk access or something), or after you
|
|||
|
have shown a picture (while the viewer is admiring it, you are
|
|||
|
calculating pi to its 37th degree in the background ;-)) Another way of
|
|||
|
doing it is, after calculating it once, you save it to a file which you
|
|||
|
then load into the variable at the beginning of the program. Anyway,
|
|||
|
this is how we will calculate the table for our circle :
|
|||
|
|
|||
|
Procedure Setup;
|
|||
|
VAR deg:real;
|
|||
|
BEGIN
|
|||
|
deg:=0;
|
|||
|
for loop1:=1 to 8000 do BEGIN
|
|||
|
deg:=deg+0.4;
|
|||
|
costbl^[loop1]:=cos (rad(deg));
|
|||
|
sintbl^[loop1]:=sin (rad(deg));
|
|||
|
END;
|
|||
|
END;
|
|||
|
|
|||
|
This will calculate the needed 16000 reals and place them into our two
|
|||
|
variables. The amount of time this takes is dependant on your computer.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How do I use a lookup table?
|
|||
|
|
|||
|
This is very easy. In your program, wherever you put
|
|||
|
cos (rad(deg)),
|
|||
|
you just replace it with :
|
|||
|
costbl^[deg]
|
|||
|
|
|||
|
Easy, no? Note that the new "deg" variable is now an integer, always
|
|||
|
between 1 and 8000.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Where else do I use lookup tables?
|
|||
|
|
|||
|
Lookup tables may be used in many different ways. For example, when
|
|||
|
working out 3-dimensional objects, sin and cos are needed often, and are
|
|||
|
best put in a lookup table. In a game, you may pregen the course an
|
|||
|
enemy may take when attacking. Even saving a picture (for example, a
|
|||
|
plasma screen) after generating it, then loading it up later is a form
|
|||
|
of pregeneration.
|
|||
|
|
|||
|
When you feel that your program is going much too slow, your problems
|
|||
|
may be totally sorted out by using a table. Or, maybe not. ;-)
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
As you have seen above, lookup tables aren't all that exciting, but they
|
|||
|
are useful and you need to know how to use them. The attached sample
|
|||
|
program will demonstrate just how big a difference they can make.
|
|||
|
|
|||
|
Keep on coding, and if you finish anything, let me know about it! I
|
|||
|
never get any mail, so all mail is greatly appreciated ;-)
|
|||
|
|
|||
|
Sorry, no quote today, it's hot and I'm tired. Maybe next time ;-)
|
|||
|
|
|||
|
- Denthor
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 7 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Hello! By popular request, this part is all about animation. I will be
|
|||
|
going over three methods of doing animation on a PC, and will
|
|||
|
concerntrate specifically on one, which will be demonstrated in the
|
|||
|
attached sample code.
|
|||
|
|
|||
|
Although not often used in demo coding, animation is usually used in
|
|||
|
games coding, which can be almost as rewarding ;-)
|
|||
|
|
|||
|
In this part I will also be a lot less stingy with assembler code :)
|
|||
|
Included will be a fairly fast pure assembler putpixel, an asm screen
|
|||
|
flip command, an asm icon placer, an asm partial-flip and one or two
|
|||
|
others. I will be explaining how these work in detail, so this may also
|
|||
|
be used as a bit of an asm-trainer too.
|
|||
|
|
|||
|
By the way, I apologise for this part taking so long to be released, but
|
|||
|
I only finished my exams a few days ago, and they of course took
|
|||
|
preference ;-). I have also noticed that the MailBox BBS is no longer
|
|||
|
operational, so the trainer will be uploaded regularly to the BBS lists
|
|||
|
shown at the end of this tutorial.
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
|
|||
|
on the ASPHYXIA BBS.
|
|||
|
2) Write a message in the Programming conference on the
|
|||
|
For Your Eyes Only BBS (of which I am the Moderator )
|
|||
|
This is preferred if you have a general programming query
|
|||
|
or problem others would benefit from.
|
|||
|
4) Write to Denthor, Eze or Livewire on Connectix.
|
|||
|
5) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
6) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
|
|||
|
call during varsity)
|
|||
|
7) Write to mcphail@beastie.cs.und.ac.za on InterNet, and
|
|||
|
mention the word Denthor near the top of the letter.
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> The Principals of Animation
|
|||
|
|
|||
|
I am sure all of you have seen a computer game with animation at one or
|
|||
|
other time. There are a few things that an animation sequence must do in
|
|||
|
order to give an impression of realism. Firstly, it must move,
|
|||
|
preferably using different frames to add to the realism (for example,
|
|||
|
with a man walking you should have different frames with the arms an
|
|||
|
legs in different positions). Secondly, it must not destroy the
|
|||
|
background, but restore it after it has passed over it.
|
|||
|
|
|||
|
This sounds obvious enough, but can be very difficult to code when you
|
|||
|
have no idea of how to go about achieving that.
|
|||
|
|
|||
|
In this trainer I will discuss various methods of meeting these two
|
|||
|
objectives.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Frames and Object Control
|
|||
|
|
|||
|
It is quite obvious that for most animation to succeed, you must have
|
|||
|
numerous frames of the object in various poses (such as a man with
|
|||
|
several frames of him walking). When shown one after the other, these
|
|||
|
give the impression of natural movement.
|
|||
|
|
|||
|
So, how do we store these frames? I hear you cry. Well, the obvious
|
|||
|
method is to store them in arrays. After drawing a frame in Autodesk
|
|||
|
Animator and saving it as a .CEL, we usually use the following code to
|
|||
|
load it in :
|
|||
|
|
|||
|
TYPE icon = Array [1..50,1..50] of byte;
|
|||
|
|
|||
|
VAR tree : icon;
|
|||
|
|
|||
|
Procedure LoadCEL (FileName : string; ScrPtr : pointer);
|
|||
|
var
|
|||
|
Fil : file;
|
|||
|
Buf : array [1..1024] of byte;
|
|||
|
BlocksRead, Count : word;
|
|||
|
begin
|
|||
|
assign (Fil, FileName);
|
|||
|
reset (Fil, 1);
|
|||
|
BlockRead (Fil, Buf, 800); { Read and ignore the 800 byte header }
|
|||
|
Count := 0; BlocksRead := $FFFF;
|
|||
|
while (not eof (Fil)) and (BlocksRead <> 0) do begin
|
|||
|
BlockRead (Fil, mem [seg (ScrPtr^): ofs (ScrPtr^) + Count], 1024, BlocksRead);
|
|||
|
Count := Count + 1024;
|
|||
|
end;
|
|||
|
close (Fil);
|
|||
|
end;
|
|||
|
|
|||
|
BEGIN
|
|||
|
Loadcel ('Tree.CEL',addr (tree));
|
|||
|
END.
|
|||
|
|
|||
|
We now have the 50x50 picture of TREE.CEL in our array tree. We may access
|
|||
|
this array in the usual manner (eg. col:=tree [25,30]). If the frame is
|
|||
|
large, or if you have many frames, try using pointers (see previous
|
|||
|
parts)
|
|||
|
|
|||
|
Now that we have the picture, how do we control the object? What if we
|
|||
|
want multiple trees wandering around doing their own thing? The solution
|
|||
|
is to have a record of information for each tree. A typical data
|
|||
|
structure may look like the following :
|
|||
|
|
|||
|
TYPE Treeinfo = Record
|
|||
|
x,y:word; { Where the tree is }
|
|||
|
speed:byte; { How fast the tree is moving }
|
|||
|
Direction:byte; { Where the tree is facing }
|
|||
|
frame:byte { Which animation frame the tree is
|
|||
|
currently involved in }
|
|||
|
active:boolean; { Is the tree actually supposed to be
|
|||
|
shown/used? }
|
|||
|
END;
|
|||
|
|
|||
|
VAR Forest : Array [1..20] of Treeinfo;
|
|||
|
|
|||
|
You now have 20 trees, each with their own information, location etc.
|
|||
|
These are accessed using the following means :
|
|||
|
Forest [15].x:=100;
|
|||
|
This would set the 15th tree's x coordinate to 100.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Restoring the Overwritten Background
|
|||
|
|
|||
|
I will discuss three methods of doing this. These are NOT NECESSARILY
|
|||
|
THE ONLY OR BEST WAYS TO DO THIS! You must experiment and decide which
|
|||
|
is the best for your particular type of program.
|
|||
|
|
|||
|
METHOD 1 :
|
|||
|
|
|||
|
Step 1 : Create two virtual pages, Vaddr and Vaddr2.
|
|||
|
Step 2 : Draw the background to Vaddr2.
|
|||
|
Step 3 : Flip Vaddr2 to Vaddr.
|
|||
|
Step 4 : Draw all the foreground objects onto Vaddr.
|
|||
|
Step 5 : Flip Vaddr to VGA.
|
|||
|
Step 6 : Repeat from 3 continuously.
|
|||
|
|
|||
|
In ascii, it looks like follows ...
|
|||
|
|
|||
|
+---------+ +---------+ +---------+
|
|||
|
| | | | | |
|
|||
|
| VGA | <======= | VADDR | <====== | VADDR2 |
|
|||
|
| | | (bckgnd)| | (bckgnd)|
|
|||
|
| | |+(icons) | | |
|
|||
|
+---------+ +---------+ +---------+
|
|||
|
|
|||
|
The advantages of this approach is that it is straightforward, continual
|
|||
|
reading of the background is not needed, there is no flicker and it is
|
|||
|
simple to implement. The disadvantages are that two 64000 byte virtual
|
|||
|
screens are needed, and the procedure is not very fast because of the
|
|||
|
slow speed of flipping.
|
|||
|
|
|||
|
|
|||
|
METHOD 2 :
|
|||
|
|
|||
|
Step 1 : Draw background to VGA.
|
|||
|
Step 2 : Grab portion of background that icon will be placed on.
|
|||
|
Step 3 : Place icon.
|
|||
|
Step 4 : Replace portion of background from Step 2 over icon.
|
|||
|
Step 5 : Repeat from step 2 continuously.
|
|||
|
|
|||
|
In terms of ascii ...
|
|||
|
|
|||
|
+---------+
|
|||
|
| +--|------- + Background restored (3)
|
|||
|
| * -|------> * Background saved to memory (1)
|
|||
|
| ^ |
|
|||
|
| +--|------- # Icon placed (2)
|
|||
|
+---------+
|
|||
|
|
|||
|
The advantages of this method is that very little extra memory is
|
|||
|
needed. The disadvantages are that writing to VGA is slower then writing
|
|||
|
to memory, and there may be large amounts of flicker.
|
|||
|
|
|||
|
|
|||
|
METHOD 3 :
|
|||
|
|
|||
|
Step 1 : Set up one virtual screen, VADDR.
|
|||
|
Step 2 : Draw background to VADDR.
|
|||
|
Step 3 : Flip VADDR to VGA.
|
|||
|
Step 4 : Draw icon to VGA.
|
|||
|
Step 5 : Transfer background portion from VADDR to VGA.
|
|||
|
Step 6 : Repeat from step 4 continuously.
|
|||
|
|
|||
|
In ascii ...
|
|||
|
|
|||
|
+---------+ +---------+
|
|||
|
| | | |
|
|||
|
| VGA | | VADDR |
|
|||
|
| | | (bckgnd)|
|
|||
|
| Icon>* <|-----------|--+ |
|
|||
|
+---------+ +---------+
|
|||
|
|
|||
|
The advantages are that writing from the virtual screen is quicker then
|
|||
|
from VGA, and there is less flicker then in Method 2. Disadvantages are
|
|||
|
that you are using a 64000 byte virtual screen, and flickering occurs
|
|||
|
with large numbers of objects.
|
|||
|
|
|||
|
In the attached sample program, a mixture of Method 3 and Method 1 is
|
|||
|
used. It is faster then Method 1, and has no flicker, unlike Method 3.
|
|||
|
What I do is I use VADDR2 for background, but only restore the
|
|||
|
background that has been changed to VADDR, before flipping to VGA.
|
|||
|
|
|||
|
In the sample program, you will see that I restore the entire background
|
|||
|
of each of the icons, and then place all the icons. This is because if I
|
|||
|
replace the background then place the icon on each object individually,
|
|||
|
if two objects are overlapping, one is partially overwritten.
|
|||
|
|
|||
|
The following sections are explanations of how the various assembler
|
|||
|
routines work. This will probably be fairly boring for you if you
|
|||
|
already know assembler, but should help beginners and dabblers alike.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> The ASM Putpixel
|
|||
|
|
|||
|
To begin with, I will explain a few of the ASM variables and functions :
|
|||
|
|
|||
|
<NOTE THAT THIS IS AN EXTREMELY SIMPLISTIC VIEW OF ASSEMBLY LANGUAGE!
|
|||
|
There are numerous books to advance your knowledge, and the Norton
|
|||
|
Guides assembler guide may be invaluable for people beginning to code
|
|||
|
in assembler. I haven't given you the pretty pictures you are supposed
|
|||
|
to have to help you understand it easier, I have merely laid it out like
|
|||
|
a programming language with it's own special procedures. >
|
|||
|
|
|||
|
There are 4 register variables : AX,BX,CX,DX. These are words (double
|
|||
|
bytes) with a range from 0 to 65535. You may access the high and low
|
|||
|
bytes of these by replacing the X with a "H" for high or "L" for low.
|
|||
|
For example, AL has a range from 0-255.
|
|||
|
|
|||
|
You also have two pointers : ES:DI and DS:SI. The part on the left is
|
|||
|
the segment to which you are pointing (eg $a000), and the right hand
|
|||
|
part is the offset, which is how far into the segment you are pointing.
|
|||
|
Turbo Pascal places a variable over 16k into the base of a segment, ie.
|
|||
|
DI or SI will be zero at the start of the variable.
|
|||
|
|
|||
|
If you wish to be pointing to pixel number 3000 on the VGA screen (see
|
|||
|
previous parts for the layout of the VGA screen), ES would be equal to
|
|||
|
$a000 and DI would be equal to 3000. You can quite as easily make ES or
|
|||
|
DS be equal to the offset of a virtual screen.
|
|||
|
|
|||
|
Here are a few functions that you will need to know :
|
|||
|
|
|||
|
mov destination,source This moves the value in source to
|
|||
|
destination. eg mov ax,50
|
|||
|
add destination,source This adds source to destination,
|
|||
|
the result being stored in destination
|
|||
|
mul source This multiplies AX by source. If
|
|||
|
source is a byte, the source is
|
|||
|
multiplied by AL, the result being
|
|||
|
stored in AX. If source is a word,
|
|||
|
the source is multiplied by AX, the
|
|||
|
result being stored in DX:AX
|
|||
|
movsb This moves the byte that DS:SI is
|
|||
|
pointing to into ES:DI, and
|
|||
|
increments SI and DI.
|
|||
|
movsw Same as movsb except it moves a
|
|||
|
word instead of a byte.
|
|||
|
stosw This moves AX into ES:DI. stosb
|
|||
|
moves AL into ES:DI. DI is then
|
|||
|
incremented.
|
|||
|
push register This saves the value of register by
|
|||
|
pushing it onto the stack. The
|
|||
|
register may then be altered, but
|
|||
|
will be restored to it's original
|
|||
|
value when popped.
|
|||
|
pop register This restores the value of a pushed
|
|||
|
register. NOTE : Pushed values must
|
|||
|
be popped in the SAME ORDER but
|
|||
|
REVERSED.
|
|||
|
rep command This repeats Command by as many
|
|||
|
times as the value in CX
|
|||
|
|
|||
|
|
|||
|
SHL Destination,count ;
|
|||
|
and SHR Destination,count ;
|
|||
|
need a bit more explaining. As you know, computers think in ones and
|
|||
|
zeroes. Each number may be represented in this base 2 operation. A byte
|
|||
|
consists of 8 ones and zeroes (bits), and have a range from 0 to 255. A
|
|||
|
word consists of 16 ones and zeroes (bits), and has a range from 0 to
|
|||
|
65535. A double word consists of 32 bits.
|
|||
|
|
|||
|
The number 53 may be represented as follows : 00110101. Ask someone who
|
|||
|
looks clever to explain to you how to convert from binary to decimal and
|
|||
|
vice-versa.
|
|||
|
|
|||
|
What happens if you shift everything to the left? Drop the leftmost
|
|||
|
number and add a zero to the right? This is what happens :
|
|||
|
|
|||
|
00110101 = 53
|
|||
|
<-----
|
|||
|
01101010 = 106
|
|||
|
|
|||
|
As you can see, the value has doubled! In the same way, by shifting one
|
|||
|
to the right, you halve the value! This is a VERY quick way of
|
|||
|
multiplying or dividing by 2. (note that for dividing by shifting, we
|
|||
|
get the trunc of the result ... ie. 15 shr 1 = 7)
|
|||
|
|
|||
|
In assembler the format is SHL destination,count This shifts
|
|||
|
destination by as many bits in count (1=*2, 2=*4, 3=*8, 4=*16 etc)
|
|||
|
Note that a shift takes only 2 clock cycles, while a mul can take up to 133
|
|||
|
clock cycles. Quite a difference, no? Only 286es or above may have count
|
|||
|
being greater then one.
|
|||
|
|
|||
|
This is why to do the following to calculate the screen coordinates for
|
|||
|
a putpixel is very slow :
|
|||
|
|
|||
|
mov ax,[Y]
|
|||
|
mov bx,320
|
|||
|
mul bx
|
|||
|
add ax,[X]
|
|||
|
mov di,ax
|
|||
|
|
|||
|
But alas! I hear you cry. 320 is not a value you may shift by, as you
|
|||
|
may only shift by 2,4,8,16,32,64,128,256,512 etc.etc. The solution is
|
|||
|
very cunning. Watch.
|
|||
|
|
|||
|
mov bx,[X]
|
|||
|
mov dx,[Y]
|
|||
|
push bx
|
|||
|
mov bx, dx {; bx = dx = Y}
|
|||
|
mov dh, dl {; dh = dl = Y}
|
|||
|
xor dl, dl {; These 2 lines equal dx*256 }
|
|||
|
shl bx, 1
|
|||
|
shl bx, 1
|
|||
|
shl bx, 1
|
|||
|
shl bx, 1
|
|||
|
shl bx, 1
|
|||
|
shl bx, 1 {; bx = bx * 64}
|
|||
|
add dx, bx {; dx = dx + bx (ie y*320)}
|
|||
|
pop bx {; get back our x}
|
|||
|
add bx, dx {; finalise location}
|
|||
|
mov di, bx
|
|||
|
|
|||
|
Let us have a look at this a bit closer shall we?
|
|||
|
bx=dx=y dx=dx*256 ; bx=bx*64 ( Note, 256+64 = 320 )
|
|||
|
|
|||
|
dx+bx=Correct y value, just add X!
|
|||
|
|
|||
|
As you can see, in assembler, the shortest code is often not the
|
|||
|
fastest.
|
|||
|
|
|||
|
The complete putpixel procedure is as follows :
|
|||
|
|
|||
|
Procedure Putpixel (X,Y : Integer; Col : Byte; where:word);
|
|||
|
{ This puts a pixel on the screen by writing directly to memory. }
|
|||
|
BEGIN
|
|||
|
Asm
|
|||
|
push ds {; Make sure these two go out the }
|
|||
|
push es {; same they went in }
|
|||
|
mov ax,[where]
|
|||
|
mov es,ax {; Point to segment of screen }
|
|||
|
mov bx,[X]
|
|||
|
mov dx,[Y]
|
|||
|
push bx {; and this again for later}
|
|||
|
mov bx, dx {; bx = dx}
|
|||
|
mov dh, dl {; dx = dx * 256}
|
|||
|
xor dl, dl
|
|||
|
shl bx, 1
|
|||
|
shl bx, 1
|
|||
|
shl bx, 1
|
|||
|
shl bx, 1
|
|||
|
shl bx, 1
|
|||
|
shl bx, 1 {; bx = bx * 64}
|
|||
|
add dx, bx {; dx = dx + bx (ie y*320)}
|
|||
|
pop bx {; get back our x}
|
|||
|
add bx, dx {; finalise location}
|
|||
|
mov di, bx {; di = offset }
|
|||
|
{; es:di = where to go}
|
|||
|
xor al,al
|
|||
|
mov ah, [Col]
|
|||
|
mov es:[di],ah {; move the value in ah to screen
|
|||
|
point es:[di] }
|
|||
|
pop es
|
|||
|
pop ds
|
|||
|
End;
|
|||
|
END;
|
|||
|
|
|||
|
Note that with DI and SI, when you use them :
|
|||
|
mov di,50 Moves di to position 50
|
|||
|
mov [di],50 Moves 50 into the place di is pointing to
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> The Flip Procedure
|
|||
|
|
|||
|
This is fairly straightforward. We get ES:DI to point to the start of
|
|||
|
the destination screen, and DS:SI to point to the start of the source
|
|||
|
screen, then do 32000 movsw (64000 bytes).
|
|||
|
|
|||
|
procedure flip(source,dest:Word);
|
|||
|
{ This copies the entire screen at "source" to destination }
|
|||
|
begin
|
|||
|
asm
|
|||
|
push ds
|
|||
|
mov ax, [Dest]
|
|||
|
mov es, ax { ES = Segment of source }
|
|||
|
mov ax, [Source]
|
|||
|
mov ds, ax { DS = Segment of source }
|
|||
|
xor si, si { SI = 0 Faster then mov si,0 }
|
|||
|
xor di, di { DI = 0 }
|
|||
|
mov cx, 32000
|
|||
|
rep movsw { Repeat movsw 32000 times }
|
|||
|
pop ds
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
The cls procedure works in much the same way, only it moves the color
|
|||
|
into AX then uses a rep stosw (see program for details)
|
|||
|
|
|||
|
The PAL command is almost exactly the same as it's Pascal equivalent
|
|||
|
(see previous tutorials). Look in the sample code to see how it uses the
|
|||
|
out and in commands.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In Closing
|
|||
|
|
|||
|
The assembler procedures presented to you in here are not at their best.
|
|||
|
Most of these are procedures ASPHYXIA abandoned for better ones after
|
|||
|
months of use. But, as you will soon see, they are all MUCH faster then
|
|||
|
the original Pascal equivalents I originally gave you. In future, I
|
|||
|
hope to give you more and more assembler procedures for your ever
|
|||
|
growing collections. But, as you know, I am not always very prompt with
|
|||
|
this series (I don't know if even one has been released within one week
|
|||
|
of the previous one), so if you want to get any stuff done, try do it
|
|||
|
yourself. What do you have to lose, aside from your temper and a few
|
|||
|
rather inventive reboots ;-)
|
|||
|
|
|||
|
What should I do for the next trainer? A simple 3-d tutorial? You may
|
|||
|
not like it, because I would go into minute detail of how it works :)
|
|||
|
Leave me suggestions for future trainers by any of the means discussed
|
|||
|
at the top of this trainer.
|
|||
|
|
|||
|
After the customary quote, I will place a listing of the BBSes I
|
|||
|
currently know that regularly carry this Trainer Series. If your BBS
|
|||
|
receives it regularly, no matter where in the country you are, get a
|
|||
|
message to me and I'll add it to the list. Let's make it more convenient
|
|||
|
for locals to grab a copy without calling long distance ;-)
|
|||
|
|
|||
|
[ There they sit, the preschooler class encircling their
|
|||
|
mentor, the substitute teacher.
|
|||
|
"Now class, today we will talk about what you want to be
|
|||
|
when you grow up. Isn't that fun?" The teacher looks
|
|||
|
around and spots the child, silent, apart from the others
|
|||
|
and deep in thought. "Jonny, why don't you start?" she
|
|||
|
encourages him.
|
|||
|
Jonny looks around, confused, his train of thought
|
|||
|
disrupted. He collects himself, and stares at the teacher
|
|||
|
with a steady eye. "I want to code demos," he says,
|
|||
|
his words becoming stronger and more confidant as he
|
|||
|
speaks. "I want to write something that will change
|
|||
|
peoples perception of reality. I want them to walk
|
|||
|
away from the computer dazed, unsure of their footing
|
|||
|
and eyesight. I want to write something that will
|
|||
|
reach out of the screen and grab them, making
|
|||
|
heartbeats and breathing slow to almost a halt. I want
|
|||
|
to write something that, when it is finished, they
|
|||
|
are reluctant to leave, knowing that nothing they
|
|||
|
experience that day will be quite as real, as
|
|||
|
insightful, as good. I want to write demos."
|
|||
|
Silence. The class and the teacher stare at Jonny, stunned. It
|
|||
|
is the teachers turn to be confused. Jonny blushes,
|
|||
|
feeling that something more is required. "Either that
|
|||
|
or I want to be a fireman."
|
|||
|
]
|
|||
|
- Grant Smith
|
|||
|
14:32
|
|||
|
21/11/93
|
|||
|
|
|||
|
See you next time,
|
|||
|
- DENTHOR
|
|||
|
|
|||
|
These fine BBS's carry the ASPHYXIA DEMO TRAINER SERIES : (alphabetical)
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
|
|||
|
<EFBFBD>BBS Name <20>Telephone No. <20>Open <20>Msg<73>File<6C>Past<73>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD>ASPHYXIA BBS #1 <20>(031) 765-5312 <20>ALL <20> * <20> * <20> * <20>
|
|||
|
<EFBFBD>ASPHYXIA BBS #2 <20>(031) 765-6293 <20>ALL <20> * <20> * <20> * <20>
|
|||
|
<EFBFBD>Connectix BBS <20>(031) 266-9992 <20>ALL <20> * <20> * <20> * <20>
|
|||
|
<EFBFBD>For Your Eyes Only BBS <20>(031) 285-318 <20>A/H <20> * <20> * <20> * <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
|
|||
|
|
|||
|
Open = Open at all times or only A/H
|
|||
|
Msg = Available in message base
|
|||
|
File = Available in file base
|
|||
|
Past = Previous Parts available
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 8 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Hello everybody! Christmas is over, the last of the chocolates have been
|
|||
|
eaten, so it's time to get on with this, the eighth part of the ASPHYXIA
|
|||
|
Demo Trainer Series. This particular part is primarily about 3-D, but
|
|||
|
also includes a bit on optimisation.
|
|||
|
|
|||
|
If you are already a 3-D guru, you may as well skip this text file, have
|
|||
|
a quick look at the sample program then go back to sleep, because I am
|
|||
|
going to explain in minute detail exactly how the routines work ;)
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
|
|||
|
on the ASPHYXIA BBS.
|
|||
|
2) Write a message in the Programming conference on the
|
|||
|
For Your Eyes Only BBS (of which I am the Moderator )
|
|||
|
This is preferred if you have a general programming query
|
|||
|
or problem others would benefit from.
|
|||
|
4) Write to Denthor, EzE or Goth on Connectix.
|
|||
|
5) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
6) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
|
|||
|
call during varsity)
|
|||
|
7) Write to mcphail@beastie.cs.und.ac.za on InterNet, and
|
|||
|
mention the word Denthor near the top of the letter.
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Optimisation
|
|||
|
|
|||
|
Before I begin with the note on 3-D, I would like to stress that many of
|
|||
|
these routines, and probably most of your own, could be sped up quite a
|
|||
|
bit with a little optimisation. One must realise, however, that you must
|
|||
|
take a look at WHAT to optimise ... converting a routine that is only
|
|||
|
called once at startup into a tightly coded assembler routine may show
|
|||
|
off your merits as a coder, but does absolutely nothing to speed up your
|
|||
|
program. Something that is called often per frame is something that
|
|||
|
needs to be as fast as possible. For some, a much used procedure is the
|
|||
|
PutPixel procedure. Here is the putpixel procedure I gave you last week:
|
|||
|
|
|||
|
Procedure Putpixel (X,Y : Integer; Col : Byte; where:word);
|
|||
|
BEGIN
|
|||
|
Asm
|
|||
|
push ds { 14 clock ticks }
|
|||
|
push es { 14 }
|
|||
|
mov ax,[where] { 8 }
|
|||
|
mov es,ax { 2 }
|
|||
|
mov bx,[X] { 8 }
|
|||
|
mov dx,[Y] { 8 }
|
|||
|
push bx { 15 }
|
|||
|
mov bx, dx { 2 }
|
|||
|
mov dh, dl { 2 }
|
|||
|
xor dl, dl { 3 }
|
|||
|
shl bx, 1 { 2 }
|
|||
|
shl bx, 1 { 2 }
|
|||
|
shl bx, 1 { 2 }
|
|||
|
shl bx, 1 { 2 }
|
|||
|
shl bx, 1 { 2 }
|
|||
|
shl bx, 1 { 2 }
|
|||
|
add dx, bx { 3 }
|
|||
|
pop bx { 12 }
|
|||
|
add bx, dx { 3 }
|
|||
|
mov di, bx { 2 }
|
|||
|
xor al,al { 3 }
|
|||
|
mov ah, [Col] { 8 }
|
|||
|
mov es:[di],ah { 10 }
|
|||
|
pop es { 12 }
|
|||
|
pop ds { 12 }
|
|||
|
End;
|
|||
|
END;
|
|||
|
Total = 153 clock ticks
|
|||
|
NOTE : Don't take my clock ticks as gospel, I probably got one or two
|
|||
|
wrong.
|
|||
|
|
|||
|
Right, now for some optimising. Firstly, if you have 286 instructions
|
|||
|
turned on, you may replace the 6 shl,1 with shl,6. Secondly, the Pascal
|
|||
|
compiler automatically pushes and pops ES, so those two lines may be
|
|||
|
removed. DS:[SI] is not altered in this procedure, so we may remove
|
|||
|
those too. Also, instead of moving COL into ah, we move it into AL and
|
|||
|
call stosb (es:[di]:=al; inc di). Let's have a look at the routine now :
|
|||
|
|
|||
|
Procedure Putpixel (X,Y : Integer; Col : Byte; where:word);
|
|||
|
BEGIN
|
|||
|
Asm
|
|||
|
mov ax,[where] { 8 }
|
|||
|
mov es,ax { 2 }
|
|||
|
mov bx,[X] { 8 }
|
|||
|
mov dx,[Y] { 8 }
|
|||
|
push bx { 15 }
|
|||
|
mov bx, dx { 2 }
|
|||
|
mov dh, dl { 2 }
|
|||
|
xor dl, dl { 3 }
|
|||
|
shl bx, 6 { 8 }
|
|||
|
add dx, bx { 3 }
|
|||
|
pop bx { 12 }
|
|||
|
add bx, dx { 3 }
|
|||
|
mov di, bx { 2 }
|
|||
|
mov al, [Col] { 8 }
|
|||
|
stosb { 11 }
|
|||
|
End;
|
|||
|
END;
|
|||
|
Total = 95 clock ticks
|
|||
|
|
|||
|
Now, let us move the value of BX directly into DI, thereby removing a
|
|||
|
costly push and pop. The MOV and the XOR of DX can be replaced by it's
|
|||
|
equivalent, SHL DX,8
|
|||
|
|
|||
|
Procedure Putpixel (X,Y : Integer; Col : Byte; where:word); assembler;
|
|||
|
asm
|
|||
|
mov ax,[where] { 8 }
|
|||
|
mov es,ax { 2 }
|
|||
|
mov bx,[X] { 8 }
|
|||
|
mov dx,[Y] { 8 }
|
|||
|
mov di,bx { 2 }
|
|||
|
mov bx, dx { 2 }
|
|||
|
shl dx, 8 { 8 }
|
|||
|
shl bx, 6 { 8 }
|
|||
|
add dx, bx { 3 }
|
|||
|
add di, dx { 3 }
|
|||
|
mov al, [Col] { 8 }
|
|||
|
stosb { 11 }
|
|||
|
end;
|
|||
|
Total = 71 clock ticks
|
|||
|
|
|||
|
As you can see, we have brought the clock ticks down from 153 ticks to
|
|||
|
71 ticks ... quite an improvement. (The current ASPHYXIA putpixel takes
|
|||
|
48 clock ticks) . As you can see, by going through your routines a few
|
|||
|
times, you can spot and remove unnecessary instructions, thereby greatly
|
|||
|
increasing the speed of your program.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Defining a 3-D object
|
|||
|
|
|||
|
Drawing an object in 3-D is not that easy. Sitting down and plotting a
|
|||
|
list of X,Y and Z points can be a time consuming business. So, let us
|
|||
|
first look at the three axes you are drawing them on :
|
|||
|
|
|||
|
Y Z
|
|||
|
/|\ /
|
|||
|
| /
|
|||
|
X<-----|----->
|
|||
|
|
|
|||
|
\|/
|
|||
|
|
|||
|
X is the horisontal axis, from left to right. Y is the vertical axis,
|
|||
|
from top to bottom. Z is the depth, going straight into the screen.
|
|||
|
|
|||
|
In this trainer, we are using lines, so we define 2 X,Y and Z
|
|||
|
coordinates, one for each end of the line. A line from far away, in the
|
|||
|
upper left of the X and Y axes, to close up in the bottom right of the
|
|||
|
X and Y axes, would look like this :
|
|||
|
|
|||
|
{ x1 y1 z1 x2 y2 z2 }
|
|||
|
( (-10,10,-10),(10,-10,10) )
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Rotating a point with matrixes
|
|||
|
|
|||
|
NOTE : I thought that more then one matix are matrisese (sp), but my
|
|||
|
spellchecker insists it is matrixes, so I let it have it's way
|
|||
|
;-)
|
|||
|
|
|||
|
Having a 3-D object is useless unless you can rotate it some way. For
|
|||
|
demonstration purposes, I will begin by working in two dimensions, X and
|
|||
|
Y.
|
|||
|
|
|||
|
Let us say you have a point, A,B, on a graph.
|
|||
|
Y
|
|||
|
| /O1 (Cos (a)*A-Sin (a)*B , Sin (a)*A+Cos (a)*B)
|
|||
|
|/ (A,B)
|
|||
|
X<-----|------O-->
|
|||
|
|
|
|||
|
|
|
|||
|
|
|||
|
Now, let us say we rotate this point by 45 degrees anti-clockwise. The
|
|||
|
new A,B can be easily be calculated using sin and cos, by an adaption of
|
|||
|
our circle algorithm, ie.
|
|||
|
A2:=Cos (45)*A - Sin (45)*B
|
|||
|
B2:=Sin (45)*A + Cos (45)*B
|
|||
|
I recall that in standard 8 and 9, we went rather heavily into this in
|
|||
|
maths. If you have troubles, fine a 8/9/10 maths book and have a look;
|
|||
|
it will go through the proofs etc.
|
|||
|
|
|||
|
Anyway, we have now rotated an object in two dimensions, AROUND THE Z
|
|||
|
AXIS. In matrix form, the equation looks like this :
|
|||
|
|
|||
|
[ Cos (a) -Sin (a) 0 0 ] [ x ]
|
|||
|
[ Sin (a) Cos (a) 0 0 ] . [ y ]
|
|||
|
[ 0 0 1 0 ] [ z ]
|
|||
|
[ 0 0 0 1 ] [ 1 ]
|
|||
|
|
|||
|
I will not go to deeply into matrixes math at this stage, as there are
|
|||
|
many books on the subject (it is not part of matric maths, however). To
|
|||
|
multiply a matrix, to add the products of the row of the left matrix and
|
|||
|
the column of the right matrix, and repeat this for all the columns of the
|
|||
|
left matrix. I don't explain it as well as my first year maths lecturer,
|
|||
|
but have a look at how I derived A2 and B2 above. Here are the other
|
|||
|
matrixes :
|
|||
|
|
|||
|
Matrix for rotation around the Y axis :
|
|||
|
[ Cos (a) 0 -Sin (a) 0 ] [ x ]
|
|||
|
[ 0 1 0 0 ] . [ y ]
|
|||
|
[ Sin (a) 0 Cos (a) 0 ] [ z ]
|
|||
|
[ 0 0 0 1 ] [ 1 ]
|
|||
|
|
|||
|
Matrix for rotation around the X axis :
|
|||
|
[ 1 0 0 ] [ x ]
|
|||
|
[ 0 Cos (a) -Sin (a) 0 ] . [ y ]
|
|||
|
[ 0 Sin (a) Cos (a) 0 ] [ z ]
|
|||
|
[ 0 0 0 1 ] [ 1 ]
|
|||
|
|
|||
|
By putting all these matrixes together, we can translate out 3D points
|
|||
|
around the origin of 0,0,0. See the sample program for how we put them
|
|||
|
together.
|
|||
|
|
|||
|
In the sample program, we have a constant, never changing base object.
|
|||
|
This is rotated into a second variable, which is then drawn. I am sure
|
|||
|
many of you can thing of cool ways to change the base object, the
|
|||
|
effects of which will appear while the object is rotating. One idea is
|
|||
|
to "pulsate" a certain point of the object according to the beat of the
|
|||
|
music being played in the background. Be creative. If you feel up to it,
|
|||
|
you could make your own version of transformers ;)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Drawing a 3D point to screen
|
|||
|
|
|||
|
Having a rotated 3D object is useless unless we can draw it to screen.
|
|||
|
But how do we show a 3D point on a 2D screen? The answer needs a bit of
|
|||
|
explaining. Examine the following diagram :
|
|||
|
|
|||
|
| ________-------------
|
|||
|
____|___------ o Object at X,Y,Z o1 Object at X,Y,Z2
|
|||
|
Eye -> O)____|___
|
|||
|
| ------________
|
|||
|
| -------------- Field of vision
|
|||
|
Screen
|
|||
|
|
|||
|
Let us pretend that the centre of the screen is the horizon of our
|
|||
|
little 3D world. If we draw a three dimensional line from object "o" to
|
|||
|
the centre of the eye, and place a pixel on the X and Y coordinates
|
|||
|
where it passes through the screen, we will notice that when we do the
|
|||
|
same with object o1, the pixel is closer to the horizon, even though
|
|||
|
their 3D X and Y coords are identical, but "o1"'s Z is larger then
|
|||
|
"o"'s. This means that the further away a point is, the closer to the
|
|||
|
horizon it is, or the smaller the object will appear. That sounds
|
|||
|
right, doesent it? But, I hear you cry, how do we translate this into a
|
|||
|
formula? The answer is quite simple. Divide your X and your Y by your Z.
|
|||
|
Think about it. The larger the number you divide by, the closer to zero,
|
|||
|
or the horizon, is the result! This means, the bigger the Z, the
|
|||
|
further away is the object! Here it is in equation form :
|
|||
|
|
|||
|
nx := 256*x div (z-Zoff)+Xoff
|
|||
|
ny := 256*y div (z-Zoff)+Yoff
|
|||
|
|
|||
|
NOTE : Zoff is how far away the entire object is, Xoff is the objects X
|
|||
|
value, and Yoff is the objects Y value. In the sample program,
|
|||
|
Xoff start off at 160 and Yoff starts off at 100, so that the
|
|||
|
object is in the middle of the screen.
|
|||
|
|
|||
|
The 256 that you times by is the perspective with which you are viewing.
|
|||
|
Changing this value gives you a "fish eye" effect when viewing the
|
|||
|
object. Anyway, there you have it! Draw a pixel at nx,ny, and viola! you
|
|||
|
are now doing 3D! Easy, wasn't it?
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Possible improvements
|
|||
|
|
|||
|
This program is not the most optimised routine you will ever encounter
|
|||
|
(;-)) ... it uses 12 muls and 2 divs per point. (Asphyxia currently has
|
|||
|
9 muls and 2 divs per point) Real math is used for all the calculations
|
|||
|
in the sample program, which is slow, so fixed point math should be
|
|||
|
implemented (I will cover fixed point math in a future trainer). The
|
|||
|
line routine currently being used is very slow. Chain-4 could be used to
|
|||
|
cut down on screen flipping times.
|
|||
|
|
|||
|
Color values per line should be added, base object morphing could be put
|
|||
|
in, polygons could be used instead of lines, handling of more then one
|
|||
|
object should be implemented, clipping should be added instead of not
|
|||
|
drawing something if any part of it is out of bounds.
|
|||
|
|
|||
|
In other words, you have a lot of work ahead of you ;)
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
There are a lot of books out there on 3D, and quite a few sample
|
|||
|
programs too. Have a look at them, and use the best bits to create your
|
|||
|
own, unique 3D engine, with which you can do anything you want. I am
|
|||
|
very interested in 3D (though EzE and Goth wrote most of ASPHYXIA'S 3D
|
|||
|
routines), and would like to see what you can do with it. Leave me a
|
|||
|
message through one of the means described above.
|
|||
|
|
|||
|
I am delving into the murky world of texture mapping. If anyone out
|
|||
|
there has some routines on the subject and are interested in swapping,
|
|||
|
give me a buzz!
|
|||
|
|
|||
|
What to do in future trainers? Help me out on this one! Are there any
|
|||
|
effects/areas you would like a bit of info on? Leave me a message!
|
|||
|
|
|||
|
I unfortunately did not get any messages regarding BBS's that carry this
|
|||
|
series, so the list that follows is the same one from last time. Give
|
|||
|
me your names, sysops!
|
|||
|
|
|||
|
Aaaaargh!!! Try as I might, I can't think of a new quote. Next time, I
|
|||
|
promise! ;-)
|
|||
|
|
|||
|
Bye for now,
|
|||
|
- Denthor
|
|||
|
|
|||
|
|
|||
|
These fine BBS's carry the ASPHYXIA DEMO TRAINER SERIES : (alphabetical)
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
|
|||
|
<EFBFBD>BBS Name <20>Telephone No. <20>Open <20>Msg<73>File<6C>Past<73>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD>ASPHYXIA BBS #1 <20>(031) 765-5312 <20>ALL <20> * <20> * <20> * <20>
|
|||
|
<EFBFBD>ASPHYXIA BBS #2 <20>(031) 765-6293 <20>ALL <20> * <20> * <20> * <20>
|
|||
|
<EFBFBD>Connectix BBS <20>(031) 266-9992 <20>ALL <20> * <20> <20> <20>
|
|||
|
<EFBFBD>For Your Eyes Only BBS <20>(031) 285-318 <20>A/H <20> * <20> * <20> * <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
|
|||
|
|
|||
|
Open = Open at all times or only A/H
|
|||
|
Msg = Available in message base
|
|||
|
File = Available in file base
|
|||
|
Past = Previous Parts available
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 9 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Hi there! ASPHYXIA is BACK with our first MegaDemo, Psycho Neurosis! A
|
|||
|
paltry 1.3MB download is all it takes to see the group from Durbs first
|
|||
|
major production! We are quite proud of it, and think you should see it
|
|||
|
;)
|
|||
|
|
|||
|
Secondly, I released a small little trainer (a trainerette ;-)) on
|
|||
|
RsaPROG and Connexctix BBS mail, also on the ASPHYXIA BBS as COPPERS.ZIP
|
|||
|
It is a small Pascal program demonstrating how to display copper bars in
|
|||
|
text mode. Also includes a check for horizontal retrace (A lot of people
|
|||
|
wanted it, that is why I wrote the program) (ASPHYXIA ... first with the
|
|||
|
trainer goodies ;-) aargh, sorry, had to be done ))
|
|||
|
|
|||
|
Thirdly, sorry about the problems with Tut 8! If you had all the
|
|||
|
checking on, the tutorial would probably die on the first points. The
|
|||
|
reason is this : in the first loop, we have DrawPoints then
|
|||
|
RotatePoints. The variables used in DrawPoints are set in RotatePoints,
|
|||
|
so if you put RotatePoints before DrawPoints, the program should work
|
|||
|
fine. Alternatively, turn off error checking 8-)
|
|||
|
|
|||
|
Fourthly, I have had a surprisingly large number of people saying that
|
|||
|
"I get this, like, strange '286 instructions not enabled' message!
|
|||
|
What's wrong with your code, dude?" To all of you, get into Pascal, hit
|
|||
|
Alt-O (for options), hit enter and a 2 (for Enable 286 instructions). Hard
|
|||
|
hey? Doesn't anyone EVER set up their version of Pascal?
|
|||
|
|
|||
|
Now, on to todays tutorial! 3D solids. That is what the people wanted,
|
|||
|
that is what the people get! This tutorial is mainly on how to draw the
|
|||
|
polygon on screen. For details on how the 3D stuff works, check out tut
|
|||
|
8.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
|
|||
|
on the ASPHYXIA BBS.
|
|||
|
2) Write to Denthor, EzE or Goth on Connectix.
|
|||
|
3) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
4) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
|
|||
|
call during varsity)
|
|||
|
5) Write to mcphail@beastie.cs.und.ac.za on InterNet, and
|
|||
|
mention the word Denthor near the top of the letter.
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How to draw a polygon
|
|||
|
|
|||
|
Sounds easy enough, right? WRONG! There are many, many different ways to
|
|||
|
go about this, and today I'll only be showing you one. Please don't take
|
|||
|
what is written here as anything approaching the best method, it is just
|
|||
|
here to get you on your way...
|
|||
|
|
|||
|
The procedure I will be using here is based on something most of us
|
|||
|
learned in standard eight ... I think. I seem to recall doing something
|
|||
|
like this in Mrs. Reids maths class all those years ago ;)
|
|||
|
|
|||
|
Take two points, x1,y1 and x2,y2. Draw them :
|
|||
|
|
|||
|
+ (x1,y1)
|
|||
|
\
|
|||
|
\ <-- Point a somewhere along the line
|
|||
|
\
|
|||
|
+ (x2,y2)
|
|||
|
|
|||
|
Right, so what we have to do is this : if we know the y-coord of a, what
|
|||
|
is it's x-coord? To prove the method we will give the points random
|
|||
|
values.
|
|||
|
|
|||
|
+ (2,10)
|
|||
|
\
|
|||
|
\ <-- a.y = 12
|
|||
|
\
|
|||
|
+ (15,30)
|
|||
|
|
|||
|
Right. Simple enough problem. This is how we do it :
|
|||
|
(a.y-y1) = (12 - 10) {to get a.y as though y1 was zero}
|
|||
|
*(x2-x1) = *(15 - 2) {the total x-length of the line}
|
|||
|
/(y2-y1) = /(30 - 10) {the total y-length of the line}
|
|||
|
+x1 = +2 { to get the equation back to real coords}
|
|||
|
|
|||
|
So our equation is : (a.y-y1)*(x2-x1)/(y2-y1)+x4 or
|
|||
|
(12-10)*(15-2)/(30-10)+2
|
|||
|
which gives you :
|
|||
|
2*13/20+2 = 26/20+2
|
|||
|
= 3.3
|
|||
|
|
|||
|
That means that along the line with y=12, x is equal to 3.3. Since we
|
|||
|
are not concerned with the decimal place, we replace the / with a div,
|
|||
|
which in Pascal gives us an integer result, and is faster too. All well
|
|||
|
and good, I hear you cry, but what does this have to do with life and
|
|||
|
how it relates to polygons in general. The answer is simple. For each of
|
|||
|
the four sides of the polygon we do the above test for each y line. We
|
|||
|
store the smallest and the largest x values into separate variables for
|
|||
|
each line, and draw a horizontal line between them. Ta-Dah! We have a
|
|||
|
cool polygon!
|
|||
|
|
|||
|
For example : Two lines going down :
|
|||
|
|
|||
|
+ +
|
|||
|
/ <-x1 x2->| <--For this y line
|
|||
|
/ |
|
|||
|
+ +
|
|||
|
|
|||
|
Find x1 and x2 for that y, then draw a line between them. Repeat for all
|
|||
|
y values.
|
|||
|
|
|||
|
Of course, it's not as simple as that. We have to make sure we only
|
|||
|
check those y lines that contain the polygon (a simple min y, max y test
|
|||
|
for all the points). We also have to check that the line we are
|
|||
|
calculating actually extends as far as where our current y is (check
|
|||
|
that the point is between both y's). We have to compare each x to see
|
|||
|
weather it is smaller then the minimum x value so far, or bigger then
|
|||
|
the maximum (the original x min is set as a high number, and the x max
|
|||
|
is set as a small number). We must also check that we only draw to the
|
|||
|
place that we can see ( 0-319 on the x ; 0-199 on the y (the size of the
|
|||
|
MCGA screen))
|
|||
|
|
|||
|
To see how this looks in practice, have a look at the sample code
|
|||
|
provided. (Mrs. Reid would probably kill me for the above explanation,
|
|||
|
so when you learn it in school, split it up into thousands of smaller
|
|||
|
equations to get the same answer ;))
|
|||
|
|
|||
|
Okay, that's it! What's that? How do you draw a vertical line? Thats
|
|||
|
simple ...
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Drawing a vertical line
|
|||
|
|
|||
|
Right, this is a lot easier than drawing a normal line (Tut 5 .. I
|
|||
|
think), because you stay on the same y value. So, what you do is you set
|
|||
|
ES to the screen you want to write to, and get DI to the start of the
|
|||
|
y-line (see earlier trainers for a description of how SEGMENT:OFFSET
|
|||
|
works.
|
|||
|
|
|||
|
IN : x1 , x2, y, color, where
|
|||
|
|
|||
|
asm
|
|||
|
mov ax,where
|
|||
|
mov es,ax
|
|||
|
mov di,y
|
|||
|
mov ax,y
|
|||
|
shl di,8 { di:=di*256 }
|
|||
|
shl ax,6 { ax:=ax*64 }
|
|||
|
add di,ax { di := (y*256)+(y*64) := y*320 Faster then a
|
|||
|
straight multiplication }
|
|||
|
|
|||
|
Right, now you add the first x value to get your startoff.
|
|||
|
add di,x1
|
|||
|
Move the color to store into ah and al
|
|||
|
mov al,color
|
|||
|
mov ah,al { ah:=al:=color }
|
|||
|
then get CX equal to how many pixels across you want to go
|
|||
|
mov cx,x2
|
|||
|
sub cx,x1 { cx:=x2-x1 }
|
|||
|
Okay, as we all know, moving a word is a lot faster then moving a byte,
|
|||
|
so we halve CX
|
|||
|
shr cx,1 { cx:=cx/2 }
|
|||
|
but what happens if CX was an odd number. After a shift, the value of
|
|||
|
the last number is placed in the carry flag, so what we do is jump over
|
|||
|
a single byte move if the carry flag is zero, or execute it if it is
|
|||
|
one.
|
|||
|
jnc @Start { If there is no carry, jump to label Start }
|
|||
|
stosb { ES:[DI]:=al ; increment DI }
|
|||
|
@Start : { Label Start }
|
|||
|
rep stosw { ES:[DI]:=ax ; DI:=DI+2; repeat CX times }
|
|||
|
|
|||
|
Right, the finished product looks like this :
|
|||
|
|
|||
|
Procedure Hline (x1,x2,y:word;col:byte;where:word); assembler;
|
|||
|
{ This draws a horizontal line from x1 to x2 on line y in color col }
|
|||
|
asm
|
|||
|
mov ax,where
|
|||
|
mov es,ax
|
|||
|
mov ax,y
|
|||
|
mov di,ax
|
|||
|
shl ax,8
|
|||
|
shl di,6
|
|||
|
add di,ax
|
|||
|
add di,x1
|
|||
|
|
|||
|
mov al,col
|
|||
|
mov ah,al
|
|||
|
mov cx,x2
|
|||
|
sub cx,x1
|
|||
|
shr cx,1
|
|||
|
jnc @start
|
|||
|
stosb
|
|||
|
@Start :
|
|||
|
rep stosw
|
|||
|
end;
|
|||
|
|
|||
|
Done!
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
This 3D system is still not perfect. It needs to be faster, and now I
|
|||
|
have also dumped the problem of face-sorting on you! Nyahahahaha!
|
|||
|
|
|||
|
[ My sister and I were driving along the other day when she
|
|||
|
asked me, what would I like for my computer.
|
|||
|
I thought long and hard about it, and came up with the
|
|||
|
following hypothesis. When a girl gets a Barbie doll, she
|
|||
|
then wants the extra ballgown for the doll, then the
|
|||
|
hairbrush, and the car, and the house, and the friends
|
|||
|
etc.
|
|||
|
When a guy gets a computer, he wants the extra memory, the
|
|||
|
bigger hard drive, the maths co-pro, the better
|
|||
|
motherboard, the latest software, and the bigger monitor
|
|||
|
etc.
|
|||
|
I told my sister all of this, and finished up with : "So as
|
|||
|
you can see, computers are Barbie dolls for MEN!"
|
|||
|
She called me a chauvinist. And hit me. Hard.
|
|||
|
]
|
|||
|
- Grant Smith
|
|||
|
19:24
|
|||
|
26/2/94
|
|||
|
|
|||
|
See you next time!
|
|||
|
- Denthor
|
|||
|
|
|||
|
These fine BBS's carry the ASPHYXIA DEMO TRAINER SERIES : (alphabetical)
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
|
|||
|
<EFBFBD>BBS Name <20>Telephone No. <20>Open <20>Msg<73>File<6C>Past<73>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD>ASPHYXIA BBS #1 <20>(031) 765-5312 <20>ALL <20> * <20> * <20> * <20>
|
|||
|
<EFBFBD>ASPHYXIA BBS #2 <20>(031) 765-6293 <20>ALL <20> * <20> * <20> * <20>
|
|||
|
<EFBFBD>Connectix BBS <20>(031) 266-9992 <20>ALL <20> <20> * <20> * <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
|
|||
|
|
|||
|
Open = Open at all times or only A/H
|
|||
|
Msg = Available in message base
|
|||
|
File = Available in file base
|
|||
|
Past = Previous Parts available
|
|||
|
|
|||
|
Does no other BBS's ANYWHERE carry the trainer? Am I writing this for
|
|||
|
three people who get it from one of these BBS's each week? Should I go
|
|||
|
on? (Hehehehe ... I was pleased to note that Tut 8 was THE most
|
|||
|
downloaded file from ASPHYXIA BBS last month ... )
|
|||
|
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 10 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Wow! The trainer has finally reached part 10! This will also be the
|
|||
|
first part introduced simultaneously to local BBS's and the INTERNET at
|
|||
|
the same time! Yes folks, I put up a copy of previous tutorials onto
|
|||
|
various ftp sites, and awaited the flames saying that the net.gurus
|
|||
|
already knew this stuff, and why was I wasting disk space! The flames
|
|||
|
did not appear (well, except for one), and I got some messages saying
|
|||
|
keep it up, so from now on I will upload all future trainers to ftp
|
|||
|
sites too (wasp.eng.ufl.edu , cs.uwp.edu etc.). I will also leave a
|
|||
|
notice in the USENET groups comp.lang.pascal and comp.sys.ibm.pc.demos
|
|||
|
when a new part is finished (Until enough people say stop ;-))
|
|||
|
|
|||
|
I can also be reached at my new E-Mail address,
|
|||
|
smith9@batis.bis.und.ac.za
|
|||
|
|
|||
|
Well, this tutorial is on Chain-4. When asked to do a trainer on
|
|||
|
Chain-4, I felt that I would be walking on much travelled ground (I have
|
|||
|
seen numerous trainers on the subject), but the people who asked me said
|
|||
|
that they hadn't seen any, so could I do one anyway? Who am I to say no?
|
|||
|
|
|||
|
The sample program attached isn't that great, but I am sure that all you
|
|||
|
people out there can immediately see the potential that Chain-4 holds.
|
|||
|
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
|
|||
|
on the ASPHYXIA BBS.
|
|||
|
2) Write to Denthor, EzE or Goth on Connectix.
|
|||
|
3) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
South Africa
|
|||
|
4) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
|
|||
|
call during varsity). Call +27-31-73-2129 if you call
|
|||
|
from outside South Africa. (It's YOUR phone bill ;-))
|
|||
|
5) Write to smith9@batis.bis.und.ac.za in E-Mail.
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> What is Chain-4?
|
|||
|
|
|||
|
You people out there all have at least 256k vga cards. Most of you have
|
|||
|
512k vga cards, and some have 1MB vga cards. But what you see on your
|
|||
|
screen, as discussed in previous trainers, is 64k of data! What happened
|
|||
|
to the other 192k??? Chain-4 is a method of using all 256k at one time.
|
|||
|
|
|||
|
The way this is done is simple. 1 screen = 64k. 64k * 4 = 256k.
|
|||
|
Therefore, chain-4 allows you to write to four screens, while displaying
|
|||
|
one of them. You can then move around these four screens to see the data
|
|||
|
on them. Think of the Chain-4 screen as a big canvas. The viewport,
|
|||
|
the bit you see out of, is a smaller rectangle which can be anywhere
|
|||
|
over the bigger canvas.
|
|||
|
|
|||
|
+----------------------------+ Chain-4 screen
|
|||
|
| +--+ |
|
|||
|
| | | <- Viewport |
|
|||
|
| +--+ |
|
|||
|
| |
|
|||
|
+----------------------------+
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> The size of the chain-4 screen
|
|||
|
|
|||
|
The Chain-4 screen, can be any size that adds up to 4 screens.
|
|||
|
|
|||
|
For example, it can be 4 screens across and one screen down, or one
|
|||
|
screen across and 4 screens down, or two screens across and two screens
|
|||
|
down, and any size in between.
|
|||
|
|
|||
|
In the sample program, the size is a constant. The size * 8 is how many
|
|||
|
pixels across there are on the chain-4 screen, ie
|
|||
|
Size = 40 = 320 pixels across = 1 screen across, 4 screens down
|
|||
|
Size = 80 = 640 pixels across = 2 screens across, 2 screens down
|
|||
|
etc.
|
|||
|
|
|||
|
We need to know the size of the screen for almost all dealings with the
|
|||
|
Chain-4 screen, for obvious reasons.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Layout of the chain-4 screen, and accessing it
|
|||
|
|
|||
|
If you will remember all the way back to Part 1 of this series, I
|
|||
|
explained that the memory layout of the MCGA screen is linear. Ie, the
|
|||
|
top left hand pixel was pixel zero, the one to the right of it was
|
|||
|
number one, the next one was number two etc. With Chain-4, things are
|
|||
|
very different.
|
|||
|
|
|||
|
Chain-4 gets the 4 screens and chains them together (hence the name :)).
|
|||
|
Each screen has a different plane value, and must be accessed
|
|||
|
differently. The reason for this is that a segment of memory is only 64k
|
|||
|
big, so that we could not fit the entire Chain-4 screen into one
|
|||
|
segment.
|
|||
|
|
|||
|
All Chain-4 screens are accessed from $a000, just like in MCGA mode.
|
|||
|
What we do is, before we write to the screen, find out what plane we are
|
|||
|
writing to, set that plane, then plot the pixel. Here is how we find out
|
|||
|
how far in to plot the pixel and what plane it is on :
|
|||
|
|
|||
|
Instead of the linear model of MCGA mode, ie :
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
|||
|
<20>00<30>01<30>02<30>03<30>04<30>05<30>06<30>07<30>08<30>09<30>10<31>11<31> ...
|
|||
|
|
|||
|
Each plane of the Chain-4 screen accesses the memory in this way :
|
|||
|
|
|||
|
Plane 0 :
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
|||
|
<20>00<30> <20> <20> <20>01<30> <20> <20> <20>02<30> <20> <20> <20> ...
|
|||
|
|
|||
|
Plane 1 :
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
|||
|
<20> <20>00<30> <20> <20> <20>01<30> <20> <20> <20>02<30> <20> <20> ...
|
|||
|
|
|||
|
Plane 2 :
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
|||
|
<20> <20> <20>00<30> <20> <20> <20>01<30> <20> <20> <20>02<30> <20> ...
|
|||
|
|
|||
|
Plane 3 :
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
|||
|
<20> <20> <20> <20>00<30> <20> <20> <20>01<30> <20> <20> <20>02<30> ...
|
|||
|
|
|||
|
In this way, by choosing the right plane to write to, we can access all
|
|||
|
of the 256k of memory available to us. The plane that we write to can
|
|||
|
easily be found by the simple calculation of x mod 4, and the x
|
|||
|
coordinate is also found by x div 4. We work out our y by multiplying
|
|||
|
it by the size of our chain-4 screen.
|
|||
|
|
|||
|
NOTE : It is possible to write to all four planes at once by setting the
|
|||
|
correct port values.
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Uses of Chain-4
|
|||
|
|
|||
|
The uses of Chain-4 are many. One could write data to one screen, then
|
|||
|
flip to it (the move_to command is almost instantaneous). This means
|
|||
|
that 64k of memory does not need to be set aside for a virtual screen,
|
|||
|
you are using the vga cards memory instead!
|
|||
|
|
|||
|
Scrolling is much easier to code for in Chain-4 mode.
|
|||
|
|
|||
|
It is possible to "tweak" the mode into other resolutions. In our demo,
|
|||
|
our vectors were in 320x240 mode, and our dot vectors were in 320x400
|
|||
|
mode.
|
|||
|
|
|||
|
The main disadvantage of chain-4 as I see it is the plane swapping,
|
|||
|
which can be slow. With a bit of clever coding however, these can be
|
|||
|
kept down to a minimum.
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> The sample programs
|
|||
|
|
|||
|
The first sample program is GFX.PAS. This is a until in which I have
|
|||
|
placed most of our routines from previous tuts. All the procedures and
|
|||
|
variables you can see under the INTERFACE section can be used in any
|
|||
|
program with GFX in the USES clause. In other words, I could do this :
|
|||
|
|
|||
|
USES GFX,crt;
|
|||
|
|
|||
|
BEGIN
|
|||
|
Setupvirtual;
|
|||
|
cls (vaddr,0);
|
|||
|
Shutdown;
|
|||
|
END.
|
|||
|
|
|||
|
This program would compile perfectly. What I suggest you do is this :
|
|||
|
Rename the file to a name that suites you (eg your group name), change
|
|||
|
the first line of the unit to that name, then add all useful procedures
|
|||
|
etc. to the unit. Make it grow :-).
|
|||
|
|
|||
|
The second file is the sample program (note the USES GFX,crt; up near
|
|||
|
the top!). The program is easy to understand and is documented. The bit
|
|||
|
that I want to draw your attention to is the constant, BIT. Because I
|
|||
|
am distributing this file to many places in text form, not binary form,
|
|||
|
I could not just add a .CEL file with the program. So what I did was
|
|||
|
write some text in one color then saved it as a .CEL . I then wrote a
|
|||
|
ten line program that did the following : Moving from left to right, it
|
|||
|
counted how many pixels were of color zero, then saved the byte value to
|
|||
|
an array. When it came across color one, is counted for how long that
|
|||
|
went on then saved the byte value and saved it to an array and so on.
|
|||
|
When it was finished, I converted the array into a text file in the
|
|||
|
CONST format. Not too cunning, but I thought I had better explain it ;-)
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
There are other documents and sample programs available on Chain-4 and
|
|||
|
it's like : Try XLIB for one...
|
|||
|
|
|||
|
Finally! Some BBS's have joined my BBS list! (Okay, only two new ones,
|
|||
|
but it's a start ;-)) All you international BBS's! If you will regularly
|
|||
|
download the tuts from an FTP site, give me your names!
|
|||
|
|
|||
|
I own a car. The car's name is Bob. A few days ago, Bob was in an
|
|||
|
accident, and now has major damage to his front. Knowing insurance, I
|
|||
|
probably won't get much, probably nothing (the other guy wasn't insured,
|
|||
|
and I am only 18 :( ). I will probably have to find work in order to pay
|
|||
|
for my repairs. The point to this meandering is this : I am upset, so if
|
|||
|
you think you are getting a quote, you can just forget it.
|
|||
|
|
|||
|
Oh, well. Life goes on!
|
|||
|
|
|||
|
See you next time,
|
|||
|
- Denthor
|
|||
|
|
|||
|
These fine BBS's carry the ASPHYXIA DEMO TRAINER SERIES : (alphabetical)
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
|
|||
|
<EFBFBD>BBS Name <20>Telephone No. <20>Open <20>Msg<73>File<6C>Past<73>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD>ASPHYXIA BBS #1 <20>(031) 765-5312 <20>ALL <20> * <20> * <20> * <20>
|
|||
|
<EFBFBD>ASPHYXIA BBS #2 <20>(031) 765-6293 <20>ALL <20> * <20> * <20> * <20>
|
|||
|
<EFBFBD>Connectix BBS <20>(031) 266-9992 <20>ALL <20> <20> * <20> * <20>
|
|||
|
<EFBFBD>POP! <20>(012) 661-1257 <20>ALL <20> <20> * <20> * <20>
|
|||
|
<EFBFBD>Pure Surf BBS <20>(031) 561-5943 <20>A/H <20> <20> * <20> * <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
|
|||
|
|
|||
|
For international users : If you live outside the Republic of South
|
|||
|
Africa, do the following : Dial +27, dont dial the first 0, but dial
|
|||
|
the rest of the number. Eg, for the ASPHYXIA BBS : +27-31-765-5312
|
|||
|
|
|||
|
Open = Open at all times or only A/H
|
|||
|
Msg = Available in message base
|
|||
|
File = Available in file base
|
|||
|
Past = Previous Parts available
|
|||
|
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 11 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Hello again everybody!
|
|||
|
|
|||
|
The reason _this_ one is delayed (every single trainer has been so far ;))
|
|||
|
is mainly due to a birthday (my 19th), and numerous tests at the
|
|||
|
university (ugh!). But anyway, here it is. The sample program this time
|
|||
|
is on cross-fading. The reason for this is that many people have
|
|||
|
commented that I should be moving over to a few basic demo effects now
|
|||
|
that we have most of the basics of VGA programming. I was also thinking
|
|||
|
of either doing sound in a future version of this trainer, or starting a
|
|||
|
separate "ASPHYXIA Sound Tutorial" series. Comments?
|
|||
|
|
|||
|
One major difference between this trainer and previous ones is that I am
|
|||
|
including binary files (pictures in this case). This means that it will
|
|||
|
not be available in the message bases of selected boards anymore, and it
|
|||
|
must be obtained from the file base. Notice will however be given of
|
|||
|
it's existence in the message base.
|
|||
|
|
|||
|
Asphyxia has formalised things a bit, and we now have a few official
|
|||
|
distribution sites for all our demos and trainers. If you would like
|
|||
|
your BBS to become a distribution site, please email me at
|
|||
|
smith9@batis.bis.und.ac.za and I will send you the necessary info.
|
|||
|
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
|
|||
|
on the ASPHYXIA BBS.
|
|||
|
2) Write to Denthor, EzE, Goth, Fubar or Nobody on Connectix.
|
|||
|
3) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
South Africa
|
|||
|
4) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
|
|||
|
call during varsity). Call +27-31-73-2129 if you call
|
|||
|
from outside South Africa. (It's YOUR phone bill ;-))
|
|||
|
5) Write to smith9@batis.bis.und.ac.za in E-Mail.
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> What is a "Crossfade"?
|
|||
|
|
|||
|
This is a simple question. When you are watching a TV program, you will
|
|||
|
often see one picture on the screen, which slowly fades to a new
|
|||
|
picture, with the new picture becoming more and more prominent and the
|
|||
|
old one becoming less and less prominent. This is a crossfade. Easy huh?
|
|||
|
|
|||
|
Perhaps, but it is not that easy to code on a computer...
|
|||
|
|
|||
|
In most demos, there is a crossfade of two colors, black and white, for
|
|||
|
example : The words 'MYDEMOTEAM' appears in large with letters, then
|
|||
|
crossfades to 'PRESENTS' in large white letters.
|
|||
|
|
|||
|
I decided to allow the programmer to have a bit of color to his
|
|||
|
crossfade, and the sample program can handle a many color crossfade.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How does a crossfade work?
|
|||
|
|
|||
|
Here comes the clever bit.
|
|||
|
|
|||
|
To do a crossfade, we load in two pictures, FROM and TO. Then, for every
|
|||
|
pixel in which they are different, put a new pixel in a third screen.
|
|||
|
|
|||
|
For example, wherever there is pixel color 9 on screen 1 and pixel color
|
|||
|
45 on screen 2, put pixel color 1 on the third screen. You then repeat
|
|||
|
this for all combinations of pixels on screen one and two, and put the
|
|||
|
results into screen 3. Here it is in ascii ...
|
|||
|
|
|||
|
Screen 1 Screen 2 Screen 3
|
|||
|
.1... .3... .1...
|
|||
|
..... ..2.. ..2..
|
|||
|
...8. + ...1. = ...3.
|
|||
|
.1... ....2 .4..2
|
|||
|
|
|||
|
Note how the values on screen 3 are sequential? We keep a count for
|
|||
|
this... The two "2"'s on screen 3 are identical, so we do not use a new
|
|||
|
color for it...
|
|||
|
|
|||
|
We also keep to pallettes ... source and dest.
|
|||
|
|
|||
|
For the above example source[1] would be the pallette of 1 in screen 1,
|
|||
|
and dest[1] would be the pallette of 3 in screen 2 (Note that screen 1
|
|||
|
and screen 2 have different pallettes)
|
|||
|
|
|||
|
When we are finished with the picture, we flip screen 3 to the vga and
|
|||
|
do the following : move the pallette from source to dest or vice versa.
|
|||
|
Thats it. No fancy screen manipulations for the crossfade, we just
|
|||
|
change the pallette. Cool, huh? It also means that you can be doing fun
|
|||
|
stuff in the foreground with unused pallette colors without your program
|
|||
|
executing at two frames per second ;)
|
|||
|
|
|||
|
The sample program is fully documented, and you shouldn't have a problem
|
|||
|
deciphering it... If you ever use this effect in a demo or game, greet
|
|||
|
me! :-)
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Problems with crossfades
|
|||
|
|
|||
|
The main problem with crossfading is this : there may only be 256 colors
|
|||
|
on screen 3, in other words, only 256 combinations of colors. In the
|
|||
|
sample program, if you load up two pics with more then 256 combinations,
|
|||
|
the program gives an error message and exits to dos. To sort this
|
|||
|
problem out, you can do two things : reduce the number of places where
|
|||
|
the two pictures intersect, or squeeze down the pallette, using
|
|||
|
Autodesk Animators "SQUEEZE" command. This reduces the number of colors
|
|||
|
used by the picture, and therefore reduces the number of combinations.
|
|||
|
The picture does however lose a bit of quality.
|
|||
|
|
|||
|
The second problem with crossfading is this : It hogs most of the
|
|||
|
colors. Whatever you want to do in the foreground, make sure you do it
|
|||
|
with as few colors as possible.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
So, what do you think? Should I continue with demo effects, or should I
|
|||
|
find more basic things to do? Perhaps I should stop and just do sound
|
|||
|
coding from now on? It is up to you, so leave me mail.
|
|||
|
|
|||
|
You will notice that the sample program can load in any .CEL files, you
|
|||
|
needn't be restricted by the ones I have given you. Try crossfading a
|
|||
|
few of your own pictures and see how it turns out. The picture of the
|
|||
|
robot was draw by Fubar for our demo Psycho Neurosis, and I then
|
|||
|
squeezed down the pallette somewhat in order for the crossfade to work.
|
|||
|
The word "ASPHYXIA" was drawn by me, also in Autodesk Animator.
|
|||
|
|
|||
|
Oh well, I had better get this off quickly, today is the last time for
|
|||
|
the next few days that I can get on to the Net. I will also be voting
|
|||
|
tomorrow! If I see a CNN camera, I'll wave (Thats me, the one on the
|
|||
|
left in the red shirt! ;-)) The next trainer will be coming from the
|
|||
|
New South Africa (TM)
|
|||
|
|
|||
|
See you next time!
|
|||
|
- Denthor
|
|||
|
- 9:16, 26 April, 1994
|
|||
|
|
|||
|
PS. Does anyone in Holland with net access want to act as a courier
|
|||
|
between myself and the Accidental Connection BBS? Please leave me mail
|
|||
|
at smith9@batis.bis.und.ac.za ....
|
|||
|
|
|||
|
The following are official ASPHYXIA distribution sites :
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
|
|||
|
<EFBFBD>BBS Name <20>Telephone No. <20>Open <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD>ASPHYXIA BBS #1 <20>+27-31-765-5312 <20>ALL <20>
|
|||
|
<EFBFBD>ASPHYXIA BBS #2 <20>+27-31-765-6293 <20>ALL <20>
|
|||
|
<EFBFBD>Connectix BBS <20>+27-31-266-9992 <20>ALL <20>
|
|||
|
<EFBFBD>POP! <20>+27-12-661-1257 <20>ALL <20>
|
|||
|
<EFBFBD>Pure Surf BBS <20>+27-31-561-5943 <20>A/H <20>
|
|||
|
<EFBFBD>Wasted Image <20>407-838-4525 <20>ALL <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
|
|||
|
|
|||
|
Leave me mail if you want to become an official Asphyxia BBS
|
|||
|
distribution site.
|
|||
|
|
|||
|
(I will find out the country code for Wasted Image later...)
|
|||
|
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 12 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Hello! :-)
|
|||
|
|
|||
|
Well, a lot has happened since the last trainer, which is the reason for
|
|||
|
the amazingly long delay. First, the elections. These were quite easy
|
|||
|
actually, I went and watched a move (Demolition Man) (Election day
|
|||
|
special, all movies R2, which is about 50 US cents), then went and voted
|
|||
|
after most voters had gone home, so no long lines ;-). Soon after were
|
|||
|
exams. These did not go too well, and I am not looking forward to the
|
|||
|
results. Finally, I got measles and pneumonia at the same time and was
|
|||
|
sent off to hospital for a few days. All in all, not events which are
|
|||
|
conducive to coding! This has meant that the trainer has been delayed,
|
|||
|
and ASPHYXIA was not able to enter into the local democompo, Dexterity
|
|||
|
'94, which we were hoping to do well in. Oh well, onward and upward!
|
|||
|
|
|||
|
This trainer is on full screen scrolling in Chain-4, by request. This is
|
|||
|
actually very easy to do (and smooth), and holds a lot of potential, as
|
|||
|
I am sure you can immediately imagine.
|
|||
|
|
|||
|
A few more things : People have been saying they have had hassles
|
|||
|
sending me email, and I have found that this is because they forget the
|
|||
|
numbers in my name. They send mail to smith@batis... which does not
|
|||
|
exist, or smith@beastie... which is my brothers account. He is getting a
|
|||
|
bit sick of forwarding my mail to me ;). The two address are :
|
|||
|
smith9@batis.bis.und.ac.za
|
|||
|
smith0@beastie.cs.und.ac.za
|
|||
|
|
|||
|
I have lost about 200k worth of email, chalk it up to my beginner status
|
|||
|
at Unix. The test to see if your mail got through? I have answered
|
|||
|
_every_ email message sent to me (no easy task), so if you haven't got a
|
|||
|
reply, please resend the message.
|
|||
|
|
|||
|
You can now also send a group message to all members of Asphyxia. Just
|
|||
|
send mail to asphyxia@beastie.cs.und.ac.za and we will all get a copy
|
|||
|
... which could mean numerous replies to one querey ;)
|
|||
|
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
|
|||
|
on the ASPHYXIA BBS.
|
|||
|
2) Write to Denthor, EzE, Goth, Fubar or Nobody on Connectix.
|
|||
|
3) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
South Africa
|
|||
|
4) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
|
|||
|
call during varsity). Call +27-31-73-2129 if you call
|
|||
|
from outside South Africa. (It's YOUR phone bill ;-))
|
|||
|
5) Write to smith9@batis.bis.und.ac.za in E-Mail.
|
|||
|
6) Write to asphyxia@beastie.cs.und.ac.za
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> What is full screen scrolling?
|
|||
|
|
|||
|
I seem to recall doing this in a previous tut, but here goes again! Full
|
|||
|
screen scrolling is when the entire screen moves in a particular
|
|||
|
direction, with the new picture scrolling on to the screen. Um. Think of
|
|||
|
movie credits. The screen, filled with text, is scrolled off the top of
|
|||
|
the screen while the new text is scrolled on from the bottom. This is
|
|||
|
full screen scrolling.
|
|||
|
|
|||
|
Full screen scrolling is not limited to movie credits. Games like Raptor
|
|||
|
have you flying over a scrolling landscape while you are shooting down
|
|||
|
the bad guys. In this tutorial we will be doing vertical scrolling, but
|
|||
|
the code can very easily be altered for horizontal scrolling too.
|
|||
|
|
|||
|
Remember that we will be using Chain-4 to do our scrolling, so you may
|
|||
|
want to brush up on tut 10 in which that was covered. I will assume a
|
|||
|
brief knowledge of how chain-4 works for this tutorial.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> The theory
|
|||
|
|
|||
|
The theory behind full screen scrolling in Chain-4 is acually very
|
|||
|
simple.
|
|||
|
|
|||
|
Picture if you will, a screen that is two monitors high. Chain-4
|
|||
|
actually has four, but for this we only need two. Now, for this screen
|
|||
|
that is two monitors high, we can only see one monitors worth. Here it
|
|||
|
is in ASCII
|
|||
|
|
|||
|
+-------------+ Screen two monitors high
|
|||
|
| |
|
|||
|
| |
|
|||
|
| |
|
|||
|
| |
|
|||
|
|+-----------+|
|
|||
|
|| ||
|
|||
|
|| ||<- This is the bit we can see, one monitors worth
|
|||
|
|| ||
|
|||
|
|+-----------+|
|
|||
|
+-------------+
|
|||
|
|
|||
|
We can move the bit we can see up or down the enlarged screen. So, for
|
|||
|
example, if the screen two monitors high had a picture on it, we could
|
|||
|
move the bit we see up and down to try glimpse the entire picture. Think
|
|||
|
of it in this way : The screen is a large painting, but we can only see
|
|||
|
though a small magnifing glass. We can move this magnifing glass around
|
|||
|
the painting, but can never see the painting all at once.
|
|||
|
|
|||
|
This actually works in our favour. Anything done outside the bit we are
|
|||
|
looking through cannot be seen, so we can do our work without changing
|
|||
|
our screen.
|
|||
|
|
|||
|
On to scrolling. The method we will use this time is as follows :
|
|||
|
|
|||
|
1) Draw the next line to be seen just above and just below the part we
|
|||
|
can see.
|
|||
|
|
|||
|
+------------+ The enlarged screen
|
|||
|
| |
|
|||
|
| |
|
|||
|
|111111111111| The new part of the picture
|
|||
|
|+----------+|
|
|||
|
|| || The bit we can see
|
|||
|
|+----------+|
|
|||
|
|111111111111| The new part of the picture
|
|||
|
+------------+
|
|||
|
|
|||
|
2) Move the view up one pixel so that the new part of the picture is
|
|||
|
visible at the top of the screen.
|
|||
|
|
|||
|
3) Repeat Steps 1) and 2) until the whole screen is filled. Our screen
|
|||
|
will look as follows :
|
|||
|
|
|||
|
+---------------+
|
|||
|
|+-------------+|
|
|||
|
||3333333333333||
|
|||
|
||2222222222222|| Viewscreen
|
|||
|
||1111111111111||
|
|||
|
|+-------------+|
|
|||
|
|333333333333333|
|
|||
|
|222222222222222|
|
|||
|
|111111111111111|
|
|||
|
+---------------+
|
|||
|
|
|||
|
Check this picture with steps 1) and 2), you will see that this is
|
|||
|
correct.
|
|||
|
|
|||
|
4) Set our viewport to the bottom of the enlarged screen.
|
|||
|
|
|||
|
+---------------+
|
|||
|
|333333333333333|
|
|||
|
|222222222222222|
|
|||
|
|111111111111111|
|
|||
|
|+-------------+|
|
|||
|
||3333333333333||
|
|||
|
||2222222222222|| New position of viewscreen
|
|||
|
||1111111111111||
|
|||
|
|+-------------+|
|
|||
|
+---------------+
|
|||
|
|
|||
|
As you can see, the bit we will be looking at is exactly the same as
|
|||
|
before, we are now just at the bottom of the larger screen instead of
|
|||
|
the top!
|
|||
|
|
|||
|
5) Jump back to 1). The entire sequence can begin again, and we can have
|
|||
|
infinate scrolling in the upward direction. Clever huh?
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Our code
|
|||
|
|
|||
|
In the sample code, we have 21 different icons. What we do is decide
|
|||
|
what the next row of icons is going to consist of. We then draw the next
|
|||
|
line of pixels above and below the viewscreen according to what icons we
|
|||
|
are displaying. We then scroll up one pixel and begin again. When we
|
|||
|
have completed a row of icons, we randomly select a new row and begin
|
|||
|
again. Our icons are 16x16, so exactly 20 fit across a 320 pixel screen.
|
|||
|
|
|||
|
When we hit the top of our enlarged screen, we flip down to the bottom
|
|||
|
which looks exactly the same as the screen we have left. In this manner
|
|||
|
we have obtained smooth, infinate full screen scrolling!
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Extra bits
|
|||
|
|
|||
|
As you will see from the code, it would be the work of but a few minutes
|
|||
|
to extend our landscape across the two unused screens, thereby allowing
|
|||
|
limited horizontal movement along with our vertical movement. In fact,
|
|||
|
the entire routine could easily be made to be a horizontal scrolling
|
|||
|
routine.
|
|||
|
|
|||
|
A map of sorts could be generated, with one byte equalling one terrain
|
|||
|
type. In this manner, the terrain scrolled over could be set, as in a
|
|||
|
flying game (Flying Shark, Raptor etc). The terrain could also easily be
|
|||
|
replaced with letters for our movie-style credits.
|
|||
|
|
|||
|
Free direction scrolling, ie scrolling in all directions, is a very
|
|||
|
different matter, with very different methods to get it to work. Perhaps
|
|||
|
this will be discussed in a later trainer. But for now, work with this,
|
|||
|
know it, understand it, and think up many great things to do with it!
|
|||
|
How about a full screen text scrolly? A game? Go wild!
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
Well, I hope you enjoyed this, the latest trainer. The sample program is
|
|||
|
a little short, but that is because the concept is so simple. Attached
|
|||
|
is a file, PICCS.DAT, which contains the terrain and letters for the
|
|||
|
sample program. They were .CEL's, which I loaded into the des^ variable,
|
|||
|
which I then dumped to disk, for easy access later. The .CEL's were
|
|||
|
drawn on short notice, but still produces some nice terrain.
|
|||
|
|
|||
|
I have recieved a few requests for future trainers, and most of them are
|
|||
|
for effects, so I guess that is what will be done from now on. A
|
|||
|
surprising number have told me not to do a sound trainer and stick with
|
|||
|
graphics stuff, with only a few asking for sound stuff, so I will hold
|
|||
|
off on that until there is more of a demand.
|
|||
|
|
|||
|
I am still open to suggestions for future trainers, and of course
|
|||
|
suggestions for improving the series. Leave me mail!
|
|||
|
|
|||
|
Hmm. A quote? Okay, let me think ....
|
|||
|
|
|||
|
[ The little devil sat atop the alpine slopes, frolicking in the
|
|||
|
snow. He threw a snowball at a nearby squirrel, which
|
|||
|
missed. The resulting avalance buried two villages and a ski
|
|||
|
resort.
|
|||
|
The little devil was scared. Avalances were bad for
|
|||
|
business. The locals would form team spirit, be nice to
|
|||
|
each other and work together and free those trapped beneath
|
|||
|
the snow, which created even more goodwill. The man
|
|||
|
downstairs didn't like goodwill. He didn't like it at
|
|||
|
all.
|
|||
|
In the blink of an eye the devil was in his penthouse
|
|||
|
apartment, dressed in his usual suit. He picked up the phone.
|
|||
|
Dialing was for mortals.
|
|||
|
"Hello, Micros..."
|
|||
|
"This is Mister Crowley", interrupted the devil.
|
|||
|
There were sounds of thumping on the other side of the
|
|||
|
phone, then there was a new voice. "Hello, Bill here, we
|
|||
|
haven't heard from you in a while, Mister Crowley." The fear
|
|||
|
of the man on the other end was almost tangible. The devil
|
|||
|
smiled.
|
|||
|
"Hello Bill. Something has come up."
|
|||
|
"No!" The man on the other side almost shouted with terror.
|
|||
|
"Not Win..."
|
|||
|
"Yes, Bill. It is time."
|
|||
|
"Havn't I paid enough for my sins? Just that one night..."
|
|||
|
The man was almost sobbing.
|
|||
|
"You are touching me, Bill. But nevertheless, it is time."
|
|||
|
"No." The man sounded beaten, alone.
|
|||
|
"Yes. Bill, it is time for a new update."
|
|||
|
]
|
|||
|
- Grant Smith
|
|||
|
14:23
|
|||
|
23-7-94
|
|||
|
|
|||
|
See you next time!
|
|||
|
- Denthor
|
|||
|
|
|||
|
The following are official ASPHYXIA distribution sites :
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
|
|||
|
<EFBFBD>BBS Name <20>Telephone No. <20>Open <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD>ASPHYXIA BBS #1 <20>+27-31-765-5312 <20>ALL <20>
|
|||
|
<EFBFBD>ASPHYXIA BBS #2 <20>+27-31-765-6293 <20>ALL <20>
|
|||
|
<EFBFBD>C-Spam BBS <20>410-531-5886 <20>ALL <20>
|
|||
|
<EFBFBD>Connectix BBS <20>+27-31-266-9992 <20>ALL <20>
|
|||
|
<EFBFBD>POP! <20>+27-12-661-1257 <20>ALL <20>
|
|||
|
<EFBFBD>Pure Surf BBS <20>+27-31-561-5943 <20>A/H <20>
|
|||
|
<EFBFBD>Soul Asylum <20>+358-0-5055041 <20>ALL <20>
|
|||
|
<EFBFBD>Wasted Image <20>407-838-4525 <20>ALL <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
|
|||
|
|
|||
|
Leave me mail if you want to become an official Asphyxia BBS
|
|||
|
distribution site.
|
|||
|
|
|||
|
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 13 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Hello again! Here I am, cooped up at home, recovering from my illness
|
|||
|
with nothing to do, so of course it is the perfect time to write another
|
|||
|
trainer! After the long delay between parts 11 and 12, two trainers in
|
|||
|
two days doesn't sound like a bad idea.
|
|||
|
|
|||
|
This trainer is on starfields, which is by request of more then one
|
|||
|
person. This is quite an easy effect, and you should have no trouble
|
|||
|
grasping the concept behind it. I will be doing a 3d starfield, a
|
|||
|
horizontal starfield is very easy with you merely incrementing a x-value
|
|||
|
for each star for each frame. I am not even going to bother doing code
|
|||
|
for that one (unless requested).
|
|||
|
|
|||
|
So I am off to go grab my antibiotics pills and I will be right back
|
|||
|
with the tutorial! ;-)
|
|||
|
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
|
|||
|
on the ASPHYXIA BBS.
|
|||
|
2) Write to Denthor, EzE, Goth, Fubar or Nobody on Connectix.
|
|||
|
3) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
South Africa
|
|||
|
4) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
|
|||
|
call during varsity). Call +27-31-73-2129 if you call
|
|||
|
from outside South Africa. (It's YOUR phone bill ;-))
|
|||
|
5) Write to smith9@batis.bis.und.ac.za in E-Mail.
|
|||
|
6) Write to asphyxia@beastie.cs.und.ac.za
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> What is a 3d starfield?
|
|||
|
|
|||
|
I am not even sure if I should do this bit. Go watch any episode of Star
|
|||
|
Trek, the movies, Star Wars, or just about any sci-fi movie. Somewhere
|
|||
|
there will be a scene where you can see stars whizzing past the
|
|||
|
viewscreen, with the ones that are further away moving slower then the
|
|||
|
ones that are passed quite close to.
|
|||
|
|
|||
|
This is a 3d starfield. If you look closely, you will see that all the
|
|||
|
stars seem to originate from a point, the point you are travelling
|
|||
|
towards. This is an illusion which thankfully happens automatically,
|
|||
|
you don't have to code for it ;)
|
|||
|
|
|||
|
Starfields look very nice, and can make a big difference to an otherwise
|
|||
|
black background. It also makes a great screen saver ;-)
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How do they work?
|
|||
|
|
|||
|
This is actually quite simple. Imagine if you will, each star in the
|
|||
|
heavens having an x,y and z coordinate, with you being at 0,0,0. Easy?
|
|||
|
Right. Now, if you were to say move forward, ie. increase your z value,
|
|||
|
to you you will still be at 0,0,0 , but all the stars z values would
|
|||
|
have appeared to decrease by the exact same amount.
|
|||
|
|
|||
|
In easier language, we decrease the z value of all the the stars so that
|
|||
|
they come closer to you, and eventually whizz past.
|
|||
|
|
|||
|
This solves all our problems. Stars that are close to us on the x and y
|
|||
|
scales will pass us by faster then those that are very far from us on
|
|||
|
the x and y scales. The only thing we must watch out for is that no star
|
|||
|
is at 0,0 , ie. exactly in front of us, otherwise there will be a
|
|||
|
collision which will not look good.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How do we code this?
|
|||
|
|
|||
|
The first thing to be done is to generate our starfield. This is quite
|
|||
|
easy, with us choosing x values between -160 and 160, and y values
|
|||
|
between -100 and 100 randomly. Each z is sequentially greater for each
|
|||
|
star so that we don't get large areas with no stars. We must remember to
|
|||
|
check that there are no stars at 0,0!
|
|||
|
|
|||
|
Okay, now we start the actual viewing section. Here are the steps :
|
|||
|
|
|||
|
1) Convert our 3-d coords into their 2-d versions. Have a look at tut 8
|
|||
|
to see how this is done, but basically we divide by z.
|
|||
|
|
|||
|
2) Clear away all old stars that may be on the screen.
|
|||
|
|
|||
|
3) Draw all our stars according to our 2-d values we have calculated in
|
|||
|
1)
|
|||
|
|
|||
|
4) Move all the stars either closer to us or further away from us by
|
|||
|
decreasing or increasing their z values respectively.
|
|||
|
|
|||
|
5) If a star's z value has passed into the negative, place it at the
|
|||
|
very back of our "queue" so that it will come around again
|
|||
|
|
|||
|
6) Jump back to 1) ad-infinitum.
|
|||
|
|
|||
|
That is, as they say, it. In our sample program the steps have been
|
|||
|
neatly placed into individual procedures for easy reading.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> What next?
|
|||
|
|
|||
|
Okay, so now we have a cool looking starfield. What next? How about
|
|||
|
adding left and right motion? A menu or a scrolly in the foreground? How
|
|||
|
about figuring out how a star tunnel works? A cool 3d routine going in
|
|||
|
front of the stars?
|
|||
|
|
|||
|
A starfield can make just about any routine look just that much more
|
|||
|
professional, and can itself be improved to be a great effect all on
|
|||
|
it's own.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
So, this was yet another effect in the series. Do you still want more
|
|||
|
effects, or what? Leave me mail with further ideas for trainers. I may
|
|||
|
not do it if you don't ask for it!
|
|||
|
|
|||
|
Oh, well, the medicine has been taken, it is time for me to go. Hello to
|
|||
|
all those people who have sent me mail, and those great guys on #coders
|
|||
|
in IRC (you know who you are). Wow. That is the first greets I have ever
|
|||
|
done in a trainer. Hmm. Maybe I'm just ill ;-)
|
|||
|
|
|||
|
Happy coding people!
|
|||
|
- Denthor
|
|||
|
19:28
|
|||
|
24-7-94
|
|||
|
|
|||
|
The following are official ASPHYXIA distribution sites :
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
|
|||
|
<EFBFBD>BBS Name <20>Telephone No. <20>Open <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD>ASPHYXIA BBS #1 <20>+27-31-765-5312 <20>ALL <20>
|
|||
|
<EFBFBD>ASPHYXIA BBS #2 <20>+27-31-765-6293 <20>ALL <20>
|
|||
|
<EFBFBD>C-Spam BBS <20>410-531-5886 <20>ALL <20>
|
|||
|
<EFBFBD>Connectix BBS <20>+27-31-266-9992 <20>ALL <20>
|
|||
|
<EFBFBD>POP! <20>+27-12-661-1257 <20>ALL <20>
|
|||
|
<EFBFBD>Soul Asylum <20>+358-0-5055041 <20>ALL <20>
|
|||
|
<EFBFBD>Wasted Image <20>407-838-4525 <20>ALL <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
|
|||
|
|
|||
|
Leave me mail if you want to become an official Asphyxia BBS
|
|||
|
distribution site.
|
|||
|
|
|||
|
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 14 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Hello there. Exams are just around the corner (again :( ), so I thought
|
|||
|
I better get round to doing the next trainer. As usual, there seems to
|
|||
|
have been a big delay between this one and the last one... sorry about
|
|||
|
that ;-)
|
|||
|
|
|||
|
Well, this trainer is mainly on four things : Glenzing, faster polys,
|
|||
|
fixed point and assembler. The sample program is basically tut 9
|
|||
|
rewritten to include the above.
|
|||
|
|
|||
|
I'll go through them in order, and hopefully you won't have any hassles
|
|||
|
grasping the concepts. By the way, do any of you read the text files? I
|
|||
|
find myself answering questions via E-Mail etc. that were discussed in
|
|||
|
the text sections of the trainers ... oh well, I'll just ramble along
|
|||
|
anyway ;-)
|
|||
|
|
|||
|
Please dont send any mail to smith9@batis.bis.und.ac.za anymore ... I
|
|||
|
don't know for how much longer the account will be valid (How can a
|
|||
|
non-BIS person get onto the BIS UNIX machine in the BIS2 directory? If
|
|||
|
his name is Denthor I suppose ;-) Oh well, I got about 8 months use out
|
|||
|
of it. The account expires on Christmas day anyway...) So anyway, please
|
|||
|
leave all messages to denthor@beastie.cs.und.ac.za
|
|||
|
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
|
|||
|
on the ASPHYXIA BBS.
|
|||
|
2) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
South Africa
|
|||
|
3) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
|
|||
|
call during varsity). Call +27-31-73-2129 if you call
|
|||
|
from outside South Africa. (It's YOUR phone bill ;-))
|
|||
|
4) Write to denthor@beastie.cs.und.ac.za in E-Mail.
|
|||
|
5) Write to asphyxia@beastie.cs.und.ac.za to get to all of
|
|||
|
us at once.
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> What is glenzing?
|
|||
|
|
|||
|
This is an easy one. Imagine, in a 3D object, that all the sides are
|
|||
|
made out of colored glass. That means that every time you look through
|
|||
|
that side, everything behind it is tinged in a certain color.
|
|||
|
|
|||
|
In ascii ...
|
|||
|
+---------+
|
|||
|
| <--|---Light blue
|
|||
|
| |
|
|||
|
+--------+ |
|
|||
|
| | <-|-----|---Dark blue
|
|||
|
| +---|-----+
|
|||
|
| <--|---------Light blue
|
|||
|
+--------+
|
|||
|
|
|||
|
So where the two sides overlap, the color values of the two sides are
|
|||
|
added. Easy huh? It is also easy to code. This is how you do it :
|
|||
|
|
|||
|
Set up your pallette to be a nice run of colors.
|
|||
|
Draw your first poly.
|
|||
|
While drawing poly 1, instead of plonking down a set pixel color, grab the
|
|||
|
backgrond pixel, add 1 to it, then put the result down.
|
|||
|
Draw your second poly.
|
|||
|
While drawing poly 2, instead of plonking down a set pixel color, grab the
|
|||
|
backgrond pixel, add 2 to it, then put the result down.
|
|||
|
and so forth.
|
|||
|
|
|||
|
So if the color behind poly 1 was 5, you would place pixel 6 down
|
|||
|
instead.
|
|||
|
|
|||
|
If you do this for every single pixel of every single side of your 3d
|
|||
|
object, you then have glenzing going. This is obviously slightly slower
|
|||
|
then just drawing an item straight, but in the sample program it goes
|
|||
|
quite quickly ... this is because of the following sections...
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Faster Polygons
|
|||
|
|
|||
|
In Tut 9, you probably noticed that we were using a multiply for every
|
|||
|
single line of the poly that we drew. This is not good. Let's find out
|
|||
|
how to speed it up, shall we...
|
|||
|
|
|||
|
With the multiply method, we went through every line, to find out the
|
|||
|
minimum x and maximum x value for that line.
|
|||
|
|
|||
|
+
|
|||
|
------/---\------- Find min x and max x, draw a line
|
|||
|
/ \ between them.
|
|||
|
+ +
|
|||
|
\ /
|
|||
|
\ /
|
|||
|
+
|
|||
|
|
|||
|
How about if we found out all the min and max x's for every line first,
|
|||
|
then just went through an array drawing them. We could do it by
|
|||
|
"scanning" each side in turn. Here is how we do it :
|
|||
|
|
|||
|
+ 1
|
|||
|
/
|
|||
|
/
|
|||
|
2 +
|
|||
|
|
|||
|
We go from point one to point two. For every single y we go down, we
|
|||
|
move a constant x value. This value is found like this :
|
|||
|
|
|||
|
xchange := (x1-x2)/(y1-y2)
|
|||
|
|
|||
|
Remember gradients? This is how you calulated the slope of a line waaay
|
|||
|
back in school. You never thought it would be any use, didn't you ;-)
|
|||
|
|
|||
|
Anyway, with this value, we can do the following :
|
|||
|
|
|||
|
For loop1:=y1 to y2 do BEGIN
|
|||
|
[ Put clever stuff here ]
|
|||
|
x:=x+xchange;
|
|||
|
END;
|
|||
|
|
|||
|
and we will go through all the x-values we need for that line. Clever,
|
|||
|
huh?
|
|||
|
|
|||
|
Now for the clever bit. You have an array, from 0 to 199 (which is all
|
|||
|
the possible y-values your onscreen poly can have). Inside this is two
|
|||
|
values, which will be your min x and your max x. You start off with the
|
|||
|
min x being a huge number, and the max x being a low number. Then you
|
|||
|
scan a side. For each y, check to see if one of the following has
|
|||
|
happened : If the x value is smaller then the xmin value in your
|
|||
|
array, make the xmin value equal to the x value
|
|||
|
If the x value is larger then the xmax value in your
|
|||
|
array, make the xmax value equal to the x value
|
|||
|
|
|||
|
The loop now looks like this :
|
|||
|
|
|||
|
For loop1:=y1 to y2 do BEGIN
|
|||
|
if x>poly[loop1,1] then poly[loop1,1]:=x;
|
|||
|
if x<poly[loop1,1] then poly[loop1,1]:=x;
|
|||
|
x:=x+xchange;
|
|||
|
END;
|
|||
|
|
|||
|
Easy? Do this for all four sides (you can change this for polys with
|
|||
|
different numbers of sides), and then you have all the x min and x max
|
|||
|
values you need to draw your polygon.
|
|||
|
|
|||
|
In the sample program, if you replaced the Hline procedure with one that
|
|||
|
draws solid lines, you could use the given drawpoly for solids.
|
|||
|
|
|||
|
Even this procedure is sped up by the next section, on fixed point.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> What is fixed point?
|
|||
|
|
|||
|
Have you ever noticed how slow reals are? I mean slooooow. You can get a
|
|||
|
massive speed increase in most programs by replacing your reals with
|
|||
|
integers, words etc. But, I hear you cry, what happens to the much
|
|||
|
needed fraction bit after the decimal point? The answer? You keep it.
|
|||
|
Here's how.
|
|||
|
|
|||
|
Let us say you have a word, which is 16 bits. If you want to use it as a
|
|||
|
fixed point value, you can separate it into 2 sections, one of which
|
|||
|
holds the whole value, and one which holds the fraction.
|
|||
|
|
|||
|
00000000 00000000 <-Bits
|
|||
|
Whole Fraction
|
|||
|
|
|||
|
The number 6.5 would therefore be shown as follows :
|
|||
|
|
|||
|
Top byte : 6
|
|||
|
Bottom byte : 128
|
|||
|
|
|||
|
128 is half (or .5) of 256, and in the case of the fraction section, 256
|
|||
|
would equal one whole number.
|
|||
|
|
|||
|
So let us say we had 6.5 * 2. Using reals this would be a slow mul, but
|
|||
|
with fixed point ...
|
|||
|
|
|||
|
Top Byte : 6
|
|||
|
Bottom Byte : 128
|
|||
|
Value : 1664 <-This is the true value of the word
|
|||
|
ie. (top byte*256)+bottom byte).
|
|||
|
this is how the computer sees the
|
|||
|
word.
|
|||
|
1664 shl 1 = 3328 <-shl 1 is the same as *2, just faster.
|
|||
|
Top byte : 13
|
|||
|
Bottom byte : 0
|
|||
|
|
|||
|
As you can see, we got the correct result! And in a fraction of the time
|
|||
|
that a multiplication of a real would have taken us. You can add and
|
|||
|
subtract fixed point values with no hassles, and multiply and divide
|
|||
|
them by normal values too. When you need the whole value section, you
|
|||
|
can just read the high byte, or do the following
|
|||
|
|
|||
|
whole = word shr 8
|
|||
|
eg 1664 shr 8 = 6
|
|||
|
|
|||
|
As you can see, the fraction is truncated. Obviously, the more bits you
|
|||
|
set aside for the fraction section, the more accurate your calculation
|
|||
|
is, but the lesser the maximum whole number you can have. For example,
|
|||
|
in the above numbers, the maximum value of your whole number was 256, a
|
|||
|
far cry from the 65535 a normal (non fixed point) word's maximum.
|
|||
|
|
|||
|
There are a lot of hassles using fixed point (go on, try shift a
|
|||
|
negative value), most of which have to do with the fact that you have
|
|||
|
severely decreased the maximum number you may have, but trust me, the
|
|||
|
speed increase is worth it (With longintegers, and/or extended 386
|
|||
|
registers, you can even have 16x16 fixed point, which means high
|
|||
|
accuracy and high maximum values)
|
|||
|
|
|||
|
Try write a program using fixed point. It is not difficult and you will
|
|||
|
get it perfect easily. Trust me, I'm a democoder ;-)
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Assembler
|
|||
|
|
|||
|
In the sample program I used one or two assembler commands that I havent
|
|||
|
discussed with you ... here they are ...
|
|||
|
|
|||
|
imul value This is the same as mul, but for integer values. It
|
|||
|
multiplies ax by the value. If the value is a word,
|
|||
|
it returns the result in DX:AX
|
|||
|
|
|||
|
sal register,value This is the same as shl, but it is arithmetic,
|
|||
|
in other words it works on integers. If you
|
|||
|
had to shl a negative value, the result would
|
|||
|
mean nothing to you.
|
|||
|
|
|||
|
rcl register,value This is the same as shl, but after you have
|
|||
|
shifted, the value in the carry flag is placed
|
|||
|
in the now-vacated rightmost bit. The carry
|
|||
|
flag is set when you do an operation where the
|
|||
|
result is greater then the upmost possible
|
|||
|
value of the variable (usually 65535 or 32767)
|
|||
|
eg mov ax,64000
|
|||
|
shl ax,1 {<- Carry flag now = 1}
|
|||
|
|
|||
|
For more info on shifting etc, re-read tut 7, it goes into the concept
|
|||
|
in detail.
|
|||
|
|
|||
|
The sample program is basically Tut 9 rewritten. To see how the
|
|||
|
assembler stuff is working, do the following ... Go into 50 line mode
|
|||
|
(-Much- easier to debug), then hit [Alt - D] then R. A little box with
|
|||
|
all your registers, segments etc and their values will pop up. Move it
|
|||
|
down to where you want it, then go back to the program screen (Hit Alt
|
|||
|
and it's number together), and resize it so that you have both it and
|
|||
|
the register box onscreen at once (Alt - 5 to resize) ... then use F4,
|
|||
|
F7 and F8 to trace though the program (you know how). The current value
|
|||
|
of the registers will always be in that box.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
Well, that is about it. The sample program may start as being a little
|
|||
|
intimidating to some when they first look at it, just remember to read
|
|||
|
it with tut 9, very little is different, it's just with fixed point and
|
|||
|
a bit of assembler.
|
|||
|
|
|||
|
Before I forget, with Tut 13, the program crashes if you have error
|
|||
|
checking on. This is how you sort it out :
|
|||
|
|
|||
|
1) Turn off error checking or
|
|||
|
2) Make logo a pointer, and get and free the memory or
|
|||
|
3) Read the logo directly to screen or
|
|||
|
4) Use the {$M ......} command with various values at the top of the
|
|||
|
program till it works.
|
|||
|
|
|||
|
I prefer options 3 or 2, but hey ... the problem was that the logo was
|
|||
|
rather large (16k), and Pascal likes complaining ;-)
|
|||
|
|
|||
|
I am in doubt as to weather to continue doing quotes ... here is a
|
|||
|
conversation I had with Pipsy, after the group conversation got around
|
|||
|
to weather we were normal or not ...
|
|||
|
|
|||
|
Me : I'm normal.
|
|||
|
Pipsy : No your not.
|
|||
|
Me : Prove it.
|
|||
|
Pipsy : Just look at your quotes in your trainers.
|
|||
|
Me : What? You think those are weird?
|
|||
|
Pipsy : Too weird.
|
|||
|
Me : You mean that there is a weirdness line, and I crossed it?
|
|||
|
Pipsy : Yes.
|
|||
|
|
|||
|
Bit of a conversation killer that, so we stopped there.
|
|||
|
|
|||
|
Anyway, this trainer won't have a quote in it ... how about a disclaimer
|
|||
|
instead? Feel free to use it in your messages ...
|
|||
|
|
|||
|
------------------------------------------------------------------------
|
|||
|
The views expressed above are mine and not Novells. In fact, I've never
|
|||
|
worked for them in my life!
|
|||
|
|
|||
|
Byeeee....
|
|||
|
- Denthor
|
|||
|
18:57
|
|||
|
9-9-94
|
|||
|
|
|||
|
|
|||
|
The following are official ASPHYXIA distribution sites :
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
|
|||
|
<EFBFBD>BBS Name <20>Telephone No. <20>Open <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD>ASPHYXIA BBS #1 <20>+27-31-765-5312 <20>ALL <20>
|
|||
|
<EFBFBD>ASPHYXIA BBS #2 <20>+27-31-765-6293 <20>ALL <20>
|
|||
|
<EFBFBD>C-Spam BBS <20>410-531-5886 <20>ALL <20>
|
|||
|
<EFBFBD>POP! <20>+27-12-661-1257 <20>ALL <20>
|
|||
|
<EFBFBD>Soul Asylum <20>+358-0-5055041 <20>ALL <20>
|
|||
|
<EFBFBD>Wasted Image <20>407-838-4525 <20>ALL <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
|
|||
|
|
|||
|
Leave me mail if you want to become an official Asphyxia BBS
|
|||
|
distribution site.
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 15 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Hello again. As you can see, this tut is very soon after the last one.
|
|||
|
This is because of two reasons ... 1) The PCGPE ][ will be out soon, so
|
|||
|
I thought I would make sure I have more then just four new trainers for it,
|
|||
|
and 2) I am usually so late between tuts, I thought I would make up for it.
|
|||
|
|
|||
|
There is a discussion going on in Usenet, mostly saying that trainers etc.
|
|||
|
should be written a bit more formally and none of this gay banter and
|
|||
|
familiar language should be used. My "quotes" would definately be out ;-)
|
|||
|
But, until I get paid for doing this (and there don't seem to be any takers
|
|||
|
on that score), I will continue to write in this manner. My apologies to those
|
|||
|
who dont like this, but hey, its free, what did you expect?
|
|||
|
|
|||
|
This trainer is on plasmas, and the sample program actually became quite large,
|
|||
|
mostly due to the fact that there was some plasma stuff I wanted to try out.
|
|||
|
|
|||
|
The concept is very simple, at least for this plasma, so you shouldn't have
|
|||
|
any problems understanding it ... AFTER you have read the text file ...
|
|||
|
jumping straight into the source may be hazardous to your brain.
|
|||
|
|
|||
|
Plasmas are a great way to wow your friends by their wierd shapes and forms.
|
|||
|
I was at one stage going to write a game where the bad guy just had two
|
|||
|
circular plasmas instead of eyes... I am sure you will find creative and
|
|||
|
inventive new ways of doing and using plasmas.
|
|||
|
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
|
|||
|
on the ASPHYXIA BBS.
|
|||
|
2) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
South Africa
|
|||
|
3) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
|
|||
|
call during varsity). Call +27-31-73-2129 if you call
|
|||
|
from outside South Africa. (It's YOUR phone bill ;-))
|
|||
|
4) Write to denthor@beastie.cs.und.ac.za in E-Mail.
|
|||
|
5) Write to asphyxia@beastie.cs.und.ac.za to get to all of
|
|||
|
us at once.
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How do plasmas work?
|
|||
|
|
|||
|
I will only cover one type of plasma here ... a realtime plasma of course.
|
|||
|
Other types of plasmas include a static picture with a pallette rotation...
|
|||
|
|
|||
|
When you get right down to it, this method of realtime plasmas is merely an
|
|||
|
intersection of four COS waves. We get our color at a particular point by
|
|||
|
saying :
|
|||
|
col := costbl[one]+costbl[two]+costbl[three]+costbl[four];
|
|||
|
|
|||
|
The trick is getting the four indexes of that cos table array to create
|
|||
|
something that looks nice. This is how we organise it : Have two of them
|
|||
|
being indexes for vertical movement and two of them being indexes for
|
|||
|
horizontal movement.
|
|||
|
|
|||
|
This means that by changing these values we can move along the plasma. To
|
|||
|
draw an individual screen, we pass the values of the four to another four
|
|||
|
so that we do not disturb the origional values. For every pixel across, we
|
|||
|
add values to the first two indexes, then display the next pixel. For
|
|||
|
every row down, we add values to the second two indexes. Sound complex
|
|||
|
enough? Good, because that what we want, a complex shape on the screen.
|
|||
|
|
|||
|
By altering the origional four values, we can get all sorts of cool movement
|
|||
|
and cycling of the plasma. The reason we use a cos table is as follows :
|
|||
|
a cos table has a nice curve in the value of the numbers ... when you
|
|||
|
put two or more together, it is possible to get circular pictures ...
|
|||
|
circles are hard to do on a computer, so this makes it a lot easier...
|
|||
|
|
|||
|
Okay, now you can have a look at the source file, all I do is put the above
|
|||
|
into practice. I did add one or two things though ...
|
|||
|
|
|||
|
Background : This is just a large array, with the values in the array being
|
|||
|
added to the plasma at that pixel.
|
|||
|
|
|||
|
Psychadelic : This cycles through about 7000 colors instead of just rotating
|
|||
|
through the base 256.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Clever fading
|
|||
|
|
|||
|
You will notice when the sample program fades in and out that the colors
|
|||
|
all reach their destination at the same time ... it other words, they don't
|
|||
|
all increment by one until they hit the right color then stop. When done
|
|||
|
in that way the fading does not look as professional.
|
|||
|
|
|||
|
Here is how we do a step-crossfade.
|
|||
|
|
|||
|
Each r,g,b value can be between 0 and 64. Have the pallette we want to get
|
|||
|
to in bob and the temporary pallette in bob2. For each step, from 0 to 63
|
|||
|
do the following :
|
|||
|
bob2[loop1].r:=bob[loop1].r*step/64;
|
|||
|
|
|||
|
That means if we are halfway through the crossfade (step=32) and the red
|
|||
|
value is meant to get to 16, our equation looks like this :
|
|||
|
r:=16*32/64
|
|||
|
r=8
|
|||
|
|
|||
|
Which is half of the way to where it wants to be. This means all colors will
|
|||
|
fade in/out with the same ratios... and look nicer.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Rotating the pallette
|
|||
|
|
|||
|
I have done this one before I think .. here it is ...
|
|||
|
|
|||
|
move color 0 into temp
|
|||
|
|
|||
|
move color 1 into color 0
|
|||
|
move color 2 into color 1
|
|||
|
move color 3 into color 2
|
|||
|
and so on till color 255
|
|||
|
|
|||
|
move temp into color 255
|
|||
|
|
|||
|
And you pallette is rotating. Easy huh? Recheck tut 2 for more info on
|
|||
|
pallette rotation
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
The text file was a bit short this time, but that is mostly because the
|
|||
|
sample file is self explanitory. The file can however be speeded up, and
|
|||
|
of course you can add certain things which will totally change the look
|
|||
|
of the plasma.
|
|||
|
|
|||
|
As always, I am on the lookout for more ideas for future tuts, if you have
|
|||
|
some, mail me!
|
|||
|
|
|||
|
No quote today, this lan doesn't encourage creative thinking ;) However,
|
|||
|
there will be quotes in future as I have been told that some people like
|
|||
|
them. Even Pipsy said this while we were playing Ctrl-Alt-Del (two player
|
|||
|
game, one has to hit ctrl and alt as the other hits del, and the person
|
|||
|
hitting the del has to do it quickly so that the computer doesnt reboot.
|
|||
|
If the computer reboots the person who was hitting ctrl and alt has won.
|
|||
|
I thought I was doing really badly against Pipsy until I found out that the
|
|||
|
computer had frozen ;-))
|
|||
|
|
|||
|
Byeeee....
|
|||
|
- Denthor
|
|||
|
14:11
|
|||
|
16-9-94
|
|||
|
|
|||
|
|
|||
|
The following are official ASPHYXIA distribution sites :
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
|
|||
|
<EFBFBD>BBS Name <20>Telephone No. <20>Open <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD>ASPHYXIA BBS #1 <20>+27-31-765-5312 <20>ALL <20>
|
|||
|
<EFBFBD>ASPHYXIA BBS #2 <20>+27-31-765-6293 <20>ALL <20>
|
|||
|
<EFBFBD>C-Spam BBS <20>410-531-5886 <20>ALL <20>
|
|||
|
<EFBFBD>POP! <20>+27-12-661-1257 <20>ALL <20>
|
|||
|
<EFBFBD>Soul Asylum <20>+358-0-5055041 <20>ALL <20>
|
|||
|
<EFBFBD>Wasted Image <20>407-838-4525 <20>ALL <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
|
|||
|
|
|||
|
Leave me mail if you want to become an official Asphyxia BBS
|
|||
|
distribution site.
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 16 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Hi there. This trainer is on the scaling of an arbitrary sized bitmap to
|
|||
|
screen in two dimensions. The sample program seems to work quite quickly,
|
|||
|
and the code is document. The scaling procedure is however totally in
|
|||
|
assembler ... hopefully this won't cause to many problems.
|
|||
|
|
|||
|
EzE has released a trainer! It is on the speeding up of 3D for normal 3D
|
|||
|
and for virtual worlds. Check it out, it is quite good (even though I get
|
|||
|
a bit of ribbing in his quote ;-)) It will be in PCGPE ][, to be released
|
|||
|
shortly.
|
|||
|
|
|||
|
I have set up a mailserver (that doesn't seem to work all the time, but
|
|||
|
the ones that miss I post manually). It works like this :
|
|||
|
|
|||
|
Send mail to denthor@beastie.cs.und.ac.za with the subject line :
|
|||
|
request-list ... it will automatically mail you back with a list of
|
|||
|
subject lines with which you can grab certain files. You will then mail me
|
|||
|
with the subject line of a specific file and it will send you a uuencoded
|
|||
|
version of that file automatically. Cool, huh?
|
|||
|
|
|||
|
Remember, no more mail to smith9@batis.bis.und.ac.za, send it all to
|
|||
|
denthor@beastie.cs.und.ac.za ! Thanks.
|
|||
|
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
|
|||
|
on the ASPHYXIA BBS.
|
|||
|
2) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
South Africa
|
|||
|
3) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
|
|||
|
call during varsity). Call +27-31-73-2129 if you call
|
|||
|
from outside South Africa. (It's YOUR phone bill ;-))
|
|||
|
4) Write to denthor@beastie.cs.und.ac.za in E-Mail.
|
|||
|
5) Write to asphyxia@beastie.cs.und.ac.za to get to all of
|
|||
|
us at once.
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> What is scaling?
|
|||
|
|
|||
|
I think that most of you know this one already, but here goes. Let us say
|
|||
|
you have a picture (10x10 pixels) and you want to draw it to a different
|
|||
|
size (say 5x7 pixel), the process of altering the picture to fit into the
|
|||
|
new size is called scaling. Scaling only works on rectangular areas.
|
|||
|
|
|||
|
With scaling to can easily strech and shrink your bitmaps.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Okay, so how do we code it?
|
|||
|
|
|||
|
Right. The way I am going to do scaling is as follows :
|
|||
|
|
|||
|
For the horizontal area, I am going to calculate a certain step value. I
|
|||
|
will then trace along the bitmap, adding this step to my position, and
|
|||
|
placing the nearest pixel on to the screen. Let me explain this simpler ...
|
|||
|
|
|||
|
Let us say I have a 10 pixel wide bitmap. I want to squish it into 5 pixels.
|
|||
|
Along the bitmap, I would draw every second pixel to screen. In ascii :
|
|||
|
|
|||
|
1234567890 13579
|
|||
|
+--------+ +---+
|
|||
|
| | | |
|
|||
|
| bitmap | | |dest
|
|||
|
| | | |
|
|||
|
+--------+ +---+
|
|||
|
|
|||
|
As you can see, by stepping through every second pixel, I have shrunk the
|
|||
|
bitmap to a width of 5 pixels.
|
|||
|
|
|||
|
The equation is as follows :
|
|||
|
|
|||
|
step = origionalwidth / wantedwidth;
|
|||
|
|
|||
|
Let us say we have a 100 pixel wide bitmap, which we want to get to 20 pixels.
|
|||
|
|
|||
|
step = 100 / 20
|
|||
|
step = 5
|
|||
|
|
|||
|
If we draw every fifth pixel from the origional bitmap, we have scaled it down
|
|||
|
correctly! This also works for all values, if step is of type real.
|
|||
|
|
|||
|
We also find the step for the height in the same way.
|
|||
|
|
|||
|
Our horizontal loop is as follows :
|
|||
|
|
|||
|
For loop1:=1 to wantedwidth do BEGIN
|
|||
|
putpixel (loop1,height,bitmap[round (curpos)],vga);
|
|||
|
curpos:=curpos+xstep;
|
|||
|
END;
|
|||
|
|
|||
|
And the vertical loop is much the same. Easy huh? So east in fact, I wrote the
|
|||
|
procedure in pure assembler for you ;-) ... don't worry, it's commented.
|
|||
|
|
|||
|
In the sample program, instead of using reals I have used fixed point math.
|
|||
|
Refer to tut 14 if you have any hassles with fixed point, it is fairly
|
|||
|
straightforward.
|
|||
|
|
|||
|
I also use psuedo 3-d perspective transforms to get the positions smooth...
|
|||
|
after Tut8, this should be a breeze.
|
|||
|
|
|||
|
There are no new commands in the assembler for you, so you should get by with
|
|||
|
what you learned in tut7/8 ... whew! A lot of back referencing there ;) We
|
|||
|
really are building on our knowledge :)
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
Well, that is about it. As you can see the concept is easy, and in fact
|
|||
|
fairly obvious, but that didn't stop me from having to sit down with a
|
|||
|
pencil and a piece of paper a few months ago and puzzle it out ;-)
|
|||
|
|
|||
|
I have a lot of work ahead of me for a while, so this may be the last
|
|||
|
trainer for a few months ... unless I can find some free time available.
|
|||
|
So please be patient!
|
|||
|
|
|||
|
|
|||
|
[ "Sir! My computer has just gone haywire!"
|
|||
|
"What?" shouts the CO. "That is a multimilliondollar machine!
|
|||
|
find out what's wrong! This is a critical time lieutenant!"
|
|||
|
"Yes sir"
|
|||
|
The young lieutenant furiously types away at the keyboard, but
|
|||
|
the machine totally ignores her.
|
|||
|
"What is going on, soldier?"
|
|||
|
"I don't know sir! It is just doing totally arbitrary things
|
|||
|
after it's assigned tasks are completed. In the computer world
|
|||
|
this is known as Denthorisms."
|
|||
|
The computer starts to make random beeps, and prints out a payroll
|
|||
|
program.
|
|||
|
"Get it working NOW soldier"
|
|||
|
The lieutenant ignores him, and contines typing. She gets partial
|
|||
|
control of the system, she can run programs, but the computer is
|
|||
|
continually running arb tasks in the background. One of the
|
|||
|
techhies who have gathered behing her suddenly cries "Hey! It's
|
|||
|
accessing the missile codes! It wants to launch them!"
|
|||
|
The typing gathers speed, but to no avail. Another techhie says
|
|||
|
"I could disconnect the computer from the link, but that would take
|
|||
|
hours! And this thing will have the codes in under five minutes
|
|||
|
at the speed it's going!"
|
|||
|
A smile forms on the lieutanants face, and she leans back in her chair.
|
|||
|
"What the hell are you doing?" yells the CO. "Why have you stopped?"
|
|||
|
Again ignoring him, the lieutenant instead turns to the techhie. "Go
|
|||
|
disconnect the machine, I know how to get you the time you need."
|
|||
|
"How on earth will you do that? The machines going at top speed!"
|
|||
|
She smiles again, leans forward, types in three letters and hits the
|
|||
|
carriage return. The computer grinds to a halt.
|
|||
|
The smile breaks into a grin. "Maybe it _does_ have it's uses after
|
|||
|
all."
|
|||
|
]
|
|||
|
- Grant Smith
|
|||
|
15:30
|
|||
|
23-9-94
|
|||
|
|
|||
|
Byeeeee.....
|
|||
|
|
|||
|
The following are official ASPHYXIA distribution sites :
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
|
|||
|
<EFBFBD>BBS Name <20>Telephone No. <20>Open <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD>ASPHYXIA BBS #1 <20>+27-31-765-5312 <20>ALL <20>
|
|||
|
<EFBFBD>ASPHYXIA BBS #2 <20>+27-31-765-6293 <20>ALL <20>
|
|||
|
<EFBFBD>C-Spam BBS <20>410-531-5886 <20>ALL <20>
|
|||
|
<EFBFBD>POP! <20>+27-12-661-1257 <20>ALL <20>
|
|||
|
<EFBFBD>Soul Asylum <20>+358-0-5055041 <20>ALL <20>
|
|||
|
<EFBFBD>Wasted Image <20>407-838-4525 <20>ALL <20>
|
|||
|
<EFBFBD>Reckless Life <20>351-01-716 67 58<35>ALL <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
|
|||
|
|
|||
|
Leave me mail if you want to become an official Asphyxia BBS
|
|||
|
distribution site.
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 17 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Hi there everybody. It's a new year, but the parties are over and it's time
|
|||
|
to get coding again!
|
|||
|
|
|||
|
My mailserver died. Various sysadmins decided it was time to upgrade the
|
|||
|
OS, and wound up nuking the hard drive :-( ... this means that request-list
|
|||
|
is not working at the moment, and I have probably lost lots of mail.
|
|||
|
|
|||
|
denthor@beastie.cs.und.ac.za is still the account to write to, and
|
|||
|
hopefully the mailserver will be back up in the near future.
|
|||
|
|
|||
|
There are various C/C++ conversions of my trainer, best of which seem to be
|
|||
|
those by Snowman ... he runs through the text files with C++ updates (and
|
|||
|
seems to point out my previous mistakes with glee ;-), as well is giving a
|
|||
|
fully documented C++ conversion of the source ... very nice stuff.
|
|||
|
|
|||
|
Also, my trainers are being put on a World Wide Web site ... it is still
|
|||
|
under construction, but go to http://www.cit.gu.edu.au/~rwong
|
|||
|
my site is at http://goth.vironix.co.za/~denthor ... it is currently pretty
|
|||
|
awful, anyone want to write a nice one for me? ;)
|
|||
|
|
|||
|
I have just about finished Asphyxia's new game, I will let you all know
|
|||
|
when it is completed.
|
|||
|
|
|||
|
Tut 16 dies with large bitmaps ... the way to sort this out is to decrease
|
|||
|
the accuracy of the fixed point from 256 to 128 ... then you can have
|
|||
|
bitmaps up to 512 pixels wide. I will be putting an updated scale routine
|
|||
|
in the gfx4.pas unit.
|
|||
|
|
|||
|
This tutor is on a few demo effects (pixel morphs and static) ... after
|
|||
|
this one, I will go on to more theory ... perhaps some more 3d stuff, such
|
|||
|
as gourad shading etc. Comments?
|
|||
|
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
|
|||
|
on the ASPHYXIA BBS.
|
|||
|
2) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
South Africa
|
|||
|
3) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
|
|||
|
call during varsity). Call +27-31-73-2129 if you call
|
|||
|
from outside South Africa. (It's YOUR phone bill ;-))
|
|||
|
4) Write to denthor@beastie.cs.und.ac.za in E-Mail.
|
|||
|
5) Write to asphyxia@beastie.cs.und.ac.za to get to all of
|
|||
|
us at once.
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Pixel Morphing
|
|||
|
|
|||
|
Have you ever lain down on your back in the grass and looked up at the
|
|||
|
cloudy sky? If you have, you have probably seen the clouds move together
|
|||
|
and create wonderful shapes ... that cloud plus that cloud together make a
|
|||
|
whale ... a ship ... a face etc.
|
|||
|
|
|||
|
We can't quite outdo mother nature, but we can sure give it a shot. The
|
|||
|
effect I am going to show you is where various pixels at different starting
|
|||
|
points move together and create an overall picture.
|
|||
|
|
|||
|
The theory behind it is simple : Each pixel has bits of data associated
|
|||
|
with it, most important of which is as follows :
|
|||
|
|
|||
|
This is my color
|
|||
|
This is where I am
|
|||
|
This is where I want to be.
|
|||
|
|
|||
|
The pixel, keeping it's color, goes from where it is to where it wants to
|
|||
|
be. Our main problem is _how_ it moves from where it is to where it wants
|
|||
|
to be. A obvious approach would be to say "If it's destination is above it,
|
|||
|
decrement it's y value, if the destination is to the left, decrement it's x
|
|||
|
value and so on."
|
|||
|
|
|||
|
This would be bad. The pixel would only ever move at set angles, as you can
|
|||
|
see below :
|
|||
|
|
|||
|
Dest O-----------------\
|
|||
|
\ <--- Path
|
|||
|
\
|
|||
|
\
|
|||
|
O Source
|
|||
|
|
|||
|
Doesn't look very nice, does it? The pixels would also take different times
|
|||
|
to get to their destination, whereas we want them to reach their points at
|
|||
|
the same time, ie :
|
|||
|
|
|||
|
Dest 1 O-------------------------------O Source 1
|
|||
|
Dest 2 O-----------------O Source 2
|
|||
|
|
|||
|
Pixels 1 and 2 must get to their destinations at the same time for the best
|
|||
|
effect. The way this is done by defining the number of frames or "hops"
|
|||
|
needed to get from source to destination. For example, we could tell pixel
|
|||
|
one it is allowed 64 hops to get to it's destination, and the same for
|
|||
|
point 2, and they would both arrive at the same time, even though pixel 2
|
|||
|
is closer.
|
|||
|
|
|||
|
The next question, it how do we move the pixels in a straight line? This is
|
|||
|
easier then you think...
|
|||
|
|
|||
|
Let us assume that for each pixel, x1,y1 is where it is, and x2,y2 is where
|
|||
|
it wants to be.
|
|||
|
|
|||
|
(x2-x1) = The distance on the X axis between the two points
|
|||
|
(y2-y1) = The distance on the Y axis between the two points
|
|||
|
|
|||
|
If we do the following :
|
|||
|
|
|||
|
dx := (x2-x1)/64;
|
|||
|
|
|||
|
we come out with a value in dx wich is very useful. If we added dx to x1 64
|
|||
|
times, the result would be x2! Let us check...
|
|||
|
|
|||
|
dx = (x2-x1)/64
|
|||
|
dx*64 = x2-x1 { Multiply both sides by 64 }
|
|||
|
dx*64+x1 = x2 { Add x1 to both sides }
|
|||
|
|
|||
|
This is high school math stuff, and is pretty self explanitory. So what we
|
|||
|
have is the x movement for every frame that the pixel has to undergo. We
|
|||
|
find the y movement in the same manner.
|
|||
|
|
|||
|
dy := (y2-y1)/64;
|
|||
|
|
|||
|
So our program is as follows :
|
|||
|
|
|||
|
Set x1,y1 and x2,y2 values
|
|||
|
dx:= (x2-x1)/64;
|
|||
|
dy:= (y2-y1)/64;
|
|||
|
|
|||
|
for loop1:=1 to 64 do BEGIN
|
|||
|
putpixel (x1,y1)
|
|||
|
wait;
|
|||
|
clear pixel (x1,y1);
|
|||
|
x1:=x1+dx;
|
|||
|
y1:=y1+dy;
|
|||
|
END;
|
|||
|
|
|||
|
If there was a compiler that could use the above pseudocode, it would move
|
|||
|
the pixel from x1,y1 to x2,y2 in 64 steps.
|
|||
|
|
|||
|
So, what we do is set up an array of many pixels with this information, and
|
|||
|
move them all at once ... viola, we have pixel morphing! It is usually best
|
|||
|
to use a bitmap which defines the color and destination of the pixels, then
|
|||
|
randomly scatter them around the screen.
|
|||
|
|
|||
|
Why not use pixel morphing on a base object in 3d? It would be the work of
|
|||
|
a moment to add in a Z axis to the above.
|
|||
|
|
|||
|
The sample program uses fixed point math in order to achieve high speeds,
|
|||
|
but it is basically the above algorithm.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Static
|
|||
|
|
|||
|
A static screen was one of the first effects Asphyxia ever did. We never
|
|||
|
actually released it because we couldn't find anywhere it would fit. Maybe
|
|||
|
you can.
|
|||
|
|
|||
|
The easiest way to get a sreen of static is to tune your TV into an unused
|
|||
|
station ... you even get the cool noise effect too. Those people who build
|
|||
|
TV's really know how to code ;-)
|
|||
|
|
|||
|
For us on a PC however, it is not as easy to generate a screen full of
|
|||
|
static (unless you desperately need a new monitor)
|
|||
|
|
|||
|
What we do is this :
|
|||
|
|
|||
|
Set colors 1-16 to various shades of grey.
|
|||
|
Fill the screen up with random pixels between colors 1 and 16
|
|||
|
Rotate the pallette of colors 1 to 16.
|
|||
|
|
|||
|
That's it! You have a screenfull of static! To get two images in one static
|
|||
|
screen, all you need to do is fade up/down the specific colors you are
|
|||
|
using for static in one of the images.
|
|||
|
|
|||
|
A nice thing about a static screen is that it is just pallette rotations
|
|||
|
... you can do lots of things in the foreground at the same time (such as a
|
|||
|
scroller).
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
Well, that is about it ... as I say, I will be doing more theory stuff in
|
|||
|
future, as individual demo effects can be thought up if you know the base
|
|||
|
stuff.
|
|||
|
|
|||
|
Note the putpixel in this GFX3.PAS unit ... it is _very_ fast .. but
|
|||
|
remember, just calling a procedure eats clock ticks... so imbed putpixels
|
|||
|
in your code if you need them. Most of the time a putpixel is not needed
|
|||
|
though.
|
|||
|
|
|||
|
PCGPE ][ will be out on the 10th of Feburary. All the new tutors will be on
|
|||
|
it (if you aren't reading this from it right now! ;-) ... grab a copy of
|
|||
|
it, it is a very useful ting to have handy.
|
|||
|
|
|||
|
I have found out that these tutors have been distributed inside paper
|
|||
|
magazines ... please remember that Denthor and Asphyxia retain full
|
|||
|
copyright to the series (as mentioned earlier in the series), and if you
|
|||
|
want to use a version in a magazine, CONTACT ME FIRST ... I will probably
|
|||
|
also modify it/cut out various unneccesary things ... other then that, you
|
|||
|
must not alter the files without my permission, or at least leave a copy of
|
|||
|
the origional with the update. Maybe I could even start up a nice column
|
|||
|
for some magazine or other :)
|
|||
|
|
|||
|
Sorry 'bout that, but it had to be said ...
|
|||
|
|
|||
|
I am writing a column for the Demuan list, a Florida-based electronic
|
|||
|
magazine ... pick it up off ftp.eng.ufl.edu ... I have written various
|
|||
|
articles, all bordering on quote-like design.
|
|||
|
|
|||
|
There are more BBS's to be added to the list at the end, but I don't have
|
|||
|
them here... this tut has taken long enough ;-)
|
|||
|
|
|||
|
Byeeeee....
|
|||
|
- Denthor
|
|||
|
|
|||
|
The following are official ASPHYXIA distribution sites :
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
|
|||
|
<EFBFBD>BBS Name <20>Telephone No. <20>Open <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD>ASPHYXIA BBS #1 <20>+27-31-765-5312 <20>ALL <20>
|
|||
|
<EFBFBD>ASPHYXIA BBS #2 <20>+27-31-765-6293 <20>ALL <20>
|
|||
|
<EFBFBD>C-Spam BBS <20>410-531-5886 <20>ALL <20>
|
|||
|
<EFBFBD>POP! <20>+27-12-661-1257 <20>ALL <20>
|
|||
|
<EFBFBD>Soul Asylum <20>+358-0-5055041 <20>ALL <20>
|
|||
|
<EFBFBD>Wasted Image <20>407-838-4525 <20>ALL <20>
|
|||
|
<EFBFBD>Reckless Life <20>351-01-716 67 58<35>ALL <20>
|
|||
|
<EFBFBD>Mach 5 BBS <20>+1 319-355-7336 <20>ALL <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
|
|||
|
|
|||
|
Leave me mail if you want to become an official Asphyxia BBS
|
|||
|
distribution site.
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 18 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Welcome back! I know, I know, you all all shocked that this tut is out so
|
|||
|
soon after the last one, but the reason for this is that I want to have Tut
|
|||
|
20 out by the time PCGPE ][ is released. I probably won't get that far, but
|
|||
|
I'll try! ;)
|
|||
|
|
|||
|
This tut is on file packing, and putting everything into one executeable
|
|||
|
file. For tut 19, I am thinking of doing a bit more on explaining
|
|||
|
assembler, and perhaps demonstrating with a fire effect or something.
|
|||
|
|
|||
|
My mailserver is back up, thanks to Nobody (that's his handle). You write
|
|||
|
to denthor@beastie.cs.und.ac.za with the subject line request-list. The
|
|||
|
mailserver checks each incoming letter for this subject line, and if it
|
|||
|
finds one of the specific strings, it mails you back a certain file. I
|
|||
|
never get to see these messages! If you want to mail me personally, give
|
|||
|
your message a unique subject name! Anyway, you can request all the tuts
|
|||
|
through this mailserver.
|
|||
|
|
|||
|
I hope you are all subscribed to the Demuan List! If not, ftp it off
|
|||
|
ftp.eng.ufl.edu every sunday. I am writing a "humor" column there until
|
|||
|
someone can figure out something else I could write ;-).
|
|||
|
|
|||
|
Pipsy wants mail! She is at cowan@beastie.cs.und.ac.za and wants to chat :)
|
|||
|
Go on, mail her. The co-founder of ctrl-alt-del, she is also a good
|
|||
|
graphics coder.
|
|||
|
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
|
|||
|
on the ASPHYXIA BBS.
|
|||
|
2) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
South Africa
|
|||
|
3) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
|
|||
|
call during varsity). Call +27-31-73-2129 if you call
|
|||
|
from outside South Africa. (It's YOUR phone bill ;-))
|
|||
|
4) Write to denthor@beastie.cs.und.ac.za in E-Mail.
|
|||
|
5) Write to asphyxia@beastie.cs.und.ac.za to get to all of
|
|||
|
us at once.
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Loading a PCX file
|
|||
|
|
|||
|
This is actually quite easy. The PCX file is divided into three sections,
|
|||
|
mainly a 128 byte header, a data section, and a 768 byte pallette.
|
|||
|
|
|||
|
You can usually ignore the 128 byte header, but here it is :
|
|||
|
|
|||
|
0 Manufacturer 10 = ZSoft .PCX file
|
|||
|
1 Version
|
|||
|
2 Encoding
|
|||
|
3 Bits Per Pixel
|
|||
|
4 XMin, Ymin, XMax, YMax (2 bytes each)
|
|||
|
12 Horizontal Resolution (2 bytes)
|
|||
|
14 Verticle Resolution (2 bytes)
|
|||
|
16 Color pallette setting (48 bytes)
|
|||
|
64 Reserved
|
|||
|
65 Number of color planes
|
|||
|
66 Bytes per line (2 bytes)
|
|||
|
68 1 = Color 2 = Grayscale (2 bytes)
|
|||
|
70 Blank (58 bytes)
|
|||
|
|
|||
|
That makes 128 bytes.
|
|||
|
|
|||
|
The pallette file, which is 768 bytes, is situated at the very end of the
|
|||
|
PCX file. The 769'th byte back should be the decimal 12, which indicates
|
|||
|
that a VGA color pallette is to follow.
|
|||
|
|
|||
|
There is one thing that we have to do to get the pallette correct in VGA ...
|
|||
|
the PCX pallette values for R,G,B are 0 to 255 respectively. To convert this
|
|||
|
to our standard (VGA) pallette, we must divide the R,G,B values by 4, to get
|
|||
|
them into a range of 0 to 63.
|
|||
|
|
|||
|
Actually decoding the image is very simple. Starting after the 128 byte
|
|||
|
header, we read a byte.
|
|||
|
|
|||
|
If the top two bits of this byte are not set, we dump the value to the screen.
|
|||
|
|
|||
|
We check bits as follows :
|
|||
|
|
|||
|
if ((temp and $c0) = $c0) then ...(bits are set)... else ...(bits are not set)
|
|||
|
|
|||
|
C0 in hex = 11000000 in binary = 192 in decimal
|
|||
|
|
|||
|
Let's look at that more closely...
|
|||
|
|
|||
|
temp and c0h
|
|||
|
temp and 11000000b
|
|||
|
|
|||
|
That means, when represented in bit format, both corresponding bits have
|
|||
|
to be set to one for the result to be one.
|
|||
|
|
|||
|
0 and 0 = 0 1 and 0 = 0 0 and 1 = 0 1 and 1 = 1
|
|||
|
|
|||
|
In the above case then, both of the top two bits of temp have to be set for
|
|||
|
the result to equal 11000000b. If it does not equal that, the top two bits
|
|||
|
are not both set, and we can put the pixel.
|
|||
|
|
|||
|
So
|
|||
|
|
|||
|
if ((temp and $c0) = $c0) then BEGIN
|
|||
|
END else BEGIN
|
|||
|
putpixel (screenpos,0,temp,vga);
|
|||
|
inc (screenpos);
|
|||
|
END;
|
|||
|
|
|||
|
If the top two bits _are_ set, things change. The bottom six bits become
|
|||
|
a loop counter, which the next byte is repeated.
|
|||
|
|
|||
|
if ((temp and $c0) = $c0) then BEGIN
|
|||
|
{ Read in next byte, temp2 here.}
|
|||
|
for loop1:=1 to (temp and $3f) do BEGIN
|
|||
|
putpixel (screenpos,0,temp2,vga);
|
|||
|
inc (screenpos);
|
|||
|
END;
|
|||
|
END else BEGIN
|
|||
|
putpixel (screenpos,0,temp,vga);
|
|||
|
inc (screenpos);
|
|||
|
END;
|
|||
|
|
|||
|
There is our PCX loader. You will note that by and'ing temp by $3f, I am
|
|||
|
and'ing it by 00111111b ... in other words, clearing the top two bits.
|
|||
|
|
|||
|
The sample program has the above in assembler, but it is the same procedure...
|
|||
|
and you can read tut 19 for more info on how to code in assembler.
|
|||
|
|
|||
|
In the sample I assume that the pic is 320x200, with a maximum size of 66432
|
|||
|
bytes.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> File packing
|
|||
|
|
|||
|
The question is simple .. how do I get all my files into one executeable?
|
|||
|
Having many small data files can start to look unprofessional.
|
|||
|
|
|||
|
An easy way to have one .exe and one .dat file when dealing with many
|
|||
|
cel's etc. is easy .... you would alter your load procedure, which looks
|
|||
|
as follows :
|
|||
|
|
|||
|
VAR temp : Array [1..5,1..256] of byte;
|
|||
|
Procedure Init;
|
|||
|
BEGIN
|
|||
|
loadcel ('pic1.cel',temp[1]);
|
|||
|
loadcel ('pic2.cel',temp[2]);
|
|||
|
loadcel ('pic3.cel',temp[3]);
|
|||
|
loadcel ('pic4.cel',temp[4]);
|
|||
|
loadcel ('pic5.cel',temp[5]);
|
|||
|
END;
|
|||
|
|
|||
|
For one complile you would do this :
|
|||
|
|
|||
|
VAR temp : Array [1..5,1..256] of byte;
|
|||
|
Procedure Init;
|
|||
|
VAR f:File;
|
|||
|
BEGIN
|
|||
|
loadcel ('pic1.cel',temp[1]);
|
|||
|
loadcel ('pic2.cel',temp[2]);
|
|||
|
loadcel ('pic3.cel',temp[3]);
|
|||
|
loadcel ('pic4.cel',temp[4]);
|
|||
|
loadcel ('pic5.cel',temp[5]);
|
|||
|
assign (f,'pic.dat');
|
|||
|
rewrite (f,1);
|
|||
|
blockwrite (f,temp,sizeof(temp));
|
|||
|
close (f);
|
|||
|
END;
|
|||
|
|
|||
|
From then on, you would do :
|
|||
|
|
|||
|
VAR temp : Array [1..5,1..256] of byte;
|
|||
|
Procedure Init;
|
|||
|
VAR f:File;
|
|||
|
BEGIN
|
|||
|
assign (f,'pic.dat');
|
|||
|
reset (f,1);
|
|||
|
blockread (f,temp,sizeof(temp));
|
|||
|
close (f);
|
|||
|
END;
|
|||
|
|
|||
|
This means that instead of five data files, you now have one! You have also
|
|||
|
stripped the 800 byte cel header too :) ... note that this will work for any
|
|||
|
form of data, not just cel files.
|
|||
|
|
|||
|
The next logical step is to include this data in the .exe file, but the
|
|||
|
question is how? In an earlier tutorial, I converted my data file to
|
|||
|
constants and placed it inside my main program. This is not good mainly
|
|||
|
because of space restrictions ... you can only have so many constants, and
|
|||
|
what if your data file is two megs big?
|
|||
|
|
|||
|
Attached with this tutorial is a solution. I have written a program that
|
|||
|
combines your data files with your executeable file, no matter how big
|
|||
|
the data is. The only thing you have to worry about is a small change in
|
|||
|
your data loading methods. Lets find out what.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Using the file packer
|
|||
|
|
|||
|
Normally you would load your data as follows :
|
|||
|
|
|||
|
Procedure Init;
|
|||
|
BEGIN
|
|||
|
loadcel ('bob.bob',temp);
|
|||
|
loadpcx ('den.pcx',VGA); { Load a PCX file }
|
|||
|
loaddat ('data.dat',lookup); { Load raw data into lookup }
|
|||
|
END;
|
|||
|
|
|||
|
Easy, hey? Now, using the file packer, you would change this to :
|
|||
|
|
|||
|
USES fpack;
|
|||
|
Procedure Init;
|
|||
|
BEGIN
|
|||
|
total := 3;
|
|||
|
infodat[1] := 'bob.bob';
|
|||
|
infodat[2] := 'den.pcx';
|
|||
|
infodat[3] := 'data.dat';
|
|||
|
loadcel (1,temp);
|
|||
|
loadpcx (2,VGA);
|
|||
|
loaddat (3,lookup);
|
|||
|
END;
|
|||
|
|
|||
|
Not too difficult? Now, this is still using the normal data files on your
|
|||
|
hard drive. You would then run PACK.EXE, select the program's .exe as the
|
|||
|
base, then select "bob.bob", "den.pcx" and "data.dat", in order (1, 2, 3).
|
|||
|
Hit "c" to contine, and it will combine the files. Your programs .exe file
|
|||
|
will be able to run independantly of the separate data files on disk,
|
|||
|
because the data files are imbedded with the .exe.
|
|||
|
|
|||
|
Let us take a closer look at the load procedures. Normally a load procedure
|
|||
|
would look as follows :
|
|||
|
|
|||
|
Procedure LoadData (name:string; p:pointer);
|
|||
|
VAR f:file;
|
|||
|
BEGIN
|
|||
|
assign (f,name);
|
|||
|
reset (f,1);
|
|||
|
blockread (f,p^,filesize(f);
|
|||
|
close (f);
|
|||
|
END;
|
|||
|
|
|||
|
In FPack.pas, we do the following :
|
|||
|
|
|||
|
Function LoadData (num:integer; p:pointer):Boolean;
|
|||
|
VAR f:file;
|
|||
|
BEGIN
|
|||
|
If pack then BEGIN
|
|||
|
assign (f,paramstr(0));
|
|||
|
reset (f,1);
|
|||
|
seek (f,infopos[num]);
|
|||
|
blockread (f, p^, infopos[num+1]-infopos[num]);
|
|||
|
close (f);
|
|||
|
END else BEGIN
|
|||
|
assign (f,infodat[num]);
|
|||
|
reset (f,1);
|
|||
|
blockread (f, p^, filesize (f));
|
|||
|
close (f);
|
|||
|
END;
|
|||
|
END;
|
|||
|
|
|||
|
As you can see, we just have two special cases depending on weather or not
|
|||
|
the .exe file has been packed yet.
|
|||
|
|
|||
|
NOTE : After you have packed the file, you CAN NOT pklite it. You can
|
|||
|
however pklite the .exe _before_ you run pack.exe ... in other
|
|||
|
words, you can not use pklite to try pack your data files.
|
|||
|
|
|||
|
PACK.EXE does have a limitation ... you can only pack 24 data files together.
|
|||
|
If you would like it to do more, mail me ... It should be easy to increase the
|
|||
|
number.
|
|||
|
|
|||
|
In the sample program, FINAL.EXE is the same as temp.pas, except it has
|
|||
|
it's PCX embedded inside it. I ran pack2.exe, selected final.exe and
|
|||
|
eye.pcx, hit "C", and there it was. You will notice that eye.pcx is not
|
|||
|
included in the directory ... it is now part of the exe!
|
|||
|
|
|||
|
eye.pcx was draw by Gary Morton of iCANDi Design. The other pcx is an old
|
|||
|
one draw by Fubar.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
Well, that's about it for this trainer... next one (as I have mentioned
|
|||
|
twice already ;) will be on assembler, with a flame routine thrown in.
|
|||
|
|
|||
|
Any good html programmers out there? My web page really needs help ;-)
|
|||
|
|
|||
|
As soon as I figure out how, I will also be creating a mailing list, in
|
|||
|
which people with internet addresses will be able to get all new trainers
|
|||
|
dilivered directly into their mailbox's. I hope to announce something in
|
|||
|
tut 20.
|
|||
|
|
|||
|
This tut has been a bit of a departure from normal tuts ... aside from the
|
|||
|
PCX loading routines, the rest has been "non programming" oriented ...
|
|||
|
don't worry, next weeks one will be back to normal.
|
|||
|
|
|||
|
|
|||
|
Byeeeee....
|
|||
|
- Denthor
|
|||
|
|
|||
|
The following are official ASPHYXIA distribution sites :
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
|
|||
|
<EFBFBD>BBS Name <20>Telephone No. <20>Open <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD>ASPHYXIA BBS #1 <20>+27-31-765-5312 <20>ALL <20> *Moving*
|
|||
|
<EFBFBD>ASPHYXIA BBS #2 <20>+27-31-765-6293 <20>ALL <20> *Moving*
|
|||
|
<EFBFBD>C-Spam BBS <20>410-531-5886 <20>ALL <20>
|
|||
|
<EFBFBD>POP! <20>+27-12-661-1257 <20>ALL <20>
|
|||
|
<EFBFBD>Soul Asylum <20>+358-0-5055041 <20>ALL <20>
|
|||
|
<EFBFBD>Wasted Image <20>407-838-4525 <20>ALL <20>
|
|||
|
<EFBFBD>Reckless Life <20>351-01-716 67 58<35>ALL <20>
|
|||
|
<EFBFBD>Mach 5 BBS <20>+1 319-355-7336 <20>ALL <20>
|
|||
|
<EFBFBD>House of Horror <20>+1 513-734-6470 <20>ALL <20>
|
|||
|
<EFBFBD>Zero Level <20>+39 6-810-9934 <20>ALL <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
|
|||
|
|
|||
|
Leave me mail if you want to become an official Asphyxia BBS
|
|||
|
distribution site.
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 19 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Hi there. As promised in Tut 18, this trainer is on assembler. For those
|
|||
|
people who already know assembler quite well, this tut is also on the flame
|
|||
|
effect.
|
|||
|
|
|||
|
Okay, here is the total list of ways to get my trainers :
|
|||
|
|
|||
|
http://goth.vironix.co.za/~denthor (WWW)
|
|||
|
ftp.eng.ufl.edu pub/msdos/demos/code/graph/tutor (FTP)
|
|||
|
denthor@beastie.cs.und.ac.za Subject : request-list (EMAIL)
|
|||
|
|
|||
|
As well as the BBS numbers shown at the end ... I will add a few ftp sits
|
|||
|
to that list (x2ftp.oulu.fi etc.)
|
|||
|
|
|||
|
Tut 20? How about 3d shading, hidden surface removal etc? Mail me :)
|
|||
|
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
|
|||
|
on the ASPHYXIA BBS.
|
|||
|
2) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
South Africa
|
|||
|
3) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
|
|||
|
call during varsity). Call +27-31-73-2129 if you call
|
|||
|
from outside South Africa. (It's YOUR phone bill ;-))
|
|||
|
4) Write to denthor@beastie.cs.und.ac.za in E-Mail.
|
|||
|
5) Write to asphyxia@beastie.cs.und.ac.za to get to all of
|
|||
|
us at once.
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Assembler - the short version
|
|||
|
|
|||
|
Okay, there are many assembler trainers out there, many of which are
|
|||
|
probably better then this one. I will focus on the areas of assembler that
|
|||
|
I find important ... if you want more, go buy a book (go for the Michael
|
|||
|
Abrash ones), or scour the 'net for others.
|
|||
|
|
|||
|
First, let us start off with the basic set up of an assembler program.
|
|||
|
|
|||
|
DOSSEG
|
|||
|
|
|||
|
This tells your assembler program to order your segments in the same manner
|
|||
|
that high level languages do.
|
|||
|
|
|||
|
.MODEL <MODEL>
|
|||
|
|
|||
|
<MODEL> can be : Tiny Code + Data < 64k (Can be made a COM file)
|
|||
|
Small Code < 64k Data < 64k
|
|||
|
Medium Code > 64k Data < 64k
|
|||
|
Compact Code < 64k Data > 64k
|
|||
|
Large Code > 64k Data > 64k
|
|||
|
Huge Arrays > 64k
|
|||
|
|
|||
|
.286
|
|||
|
|
|||
|
Enable 286 instructions ... can be .386 ; .386P etc.
|
|||
|
|
|||
|
.STACK <size>
|
|||
|
|
|||
|
<size> will be the size of your stack. I usually use 200h
|
|||
|
|
|||
|
.DATA
|
|||
|
|
|||
|
Tells the program that the data is about to follow. (Everything after this
|
|||
|
will be placed in the data segment)
|
|||
|
|
|||
|
.CODE
|
|||
|
|
|||
|
Tells the program that the code is about to follow. (Everything after this
|
|||
|
will be placed in the code segment)
|
|||
|
|
|||
|
START :
|
|||
|
|
|||
|
Tells the program that this is where the code begins.
|
|||
|
|
|||
|
END START
|
|||
|
|
|||
|
Tells the program that this is where the code ends.
|
|||
|
|
|||
|
To compile and run an assembler file, we run
|
|||
|
tasm bob
|
|||
|
tlink bob
|
|||
|
|
|||
|
I personally use tasm, you will have to find out how your assembler works.
|
|||
|
|
|||
|
Now, if we ran the above file as follows :
|
|||
|
|
|||
|
DOSSEG
|
|||
|
.MODEL SMALL
|
|||
|
.286
|
|||
|
.STACK 200h
|
|||
|
.DATA
|
|||
|
.CODE
|
|||
|
|
|||
|
START
|
|||
|
END START
|
|||
|
|
|||
|
You would think that is would just exit to dos immediately, right? Wrong.
|
|||
|
You have to specifically give dos back control, by doing the following :
|
|||
|
|
|||
|
START
|
|||
|
mov ax,4c00h
|
|||
|
int 21h
|
|||
|
END START
|
|||
|
|
|||
|
Now if you compiled it, it would run and do nothing.
|
|||
|
|
|||
|
Okay, let us kick off with registers.
|
|||
|
|
|||
|
Firstly : A bit is a value that is either 1 or 0
|
|||
|
|
|||
|
This is obviously quite limited, but if we start counting in them, we can
|
|||
|
get larger numbers. Counting with ones and zeros is known as binary, and we
|
|||
|
call it base 2. Counting in normal decimal is known as base 10, and
|
|||
|
counting in hexidecimal is known as base 16.
|
|||
|
|
|||
|
Base 2 (Binary) Base 10 (Decimal) Base 16 (Hexidecimal)
|
|||
|
0 0 0
|
|||
|
1 1 1
|
|||
|
10 2 2
|
|||
|
11 3 3
|
|||
|
100 4 4
|
|||
|
101 5 5
|
|||
|
110 6 6
|
|||
|
111 7 7
|
|||
|
1000 8 8
|
|||
|
1001 9 9
|
|||
|
1010 10 A
|
|||
|
1011 11 B
|
|||
|
1100 12 C
|
|||
|
1101 13 D
|
|||
|
1110 14 E
|
|||
|
1111 15 F
|
|||
|
|
|||
|
As you can see, you need four bits to count up to 15, and we call this a
|
|||
|
nibble. With eight bits, we can count up to 255, and we call this a byte.
|
|||
|
With sixteen bits, we can count up to 65535, and we call this a word. With
|
|||
|
thirty two bits, we can count up to lots, and we call this a double word. :)
|
|||
|
|
|||
|
A quick note : Converting from binary to hex is actually quite easy. You
|
|||
|
break up the binary into groups of four bits, starting on the right, and
|
|||
|
convers these groups of four to hex.
|
|||
|
|
|||
|
1010 0010 1111 0001
|
|||
|
= A 2 F 1
|
|||
|
|
|||
|
Converting to decimal is a bit more difficult. What you do, is you multiply
|
|||
|
each number by it's base to the power of it's index ...
|
|||
|
|
|||
|
A2F1 hex
|
|||
|
= (A*16^3) + (2*16^2) + (F*16^1) + (1*16^0)
|
|||
|
= (10*4096) + (2*256) + (15*16) + (1)
|
|||
|
= 40960 + 512 + 240 + 1
|
|||
|
= 41713 decimal
|
|||
|
|
|||
|
The same system can be used for binary.
|
|||
|
|
|||
|
To convert from decimal to another base, you divide the decimal value by the
|
|||
|
desired base, keeping a note of the remainders, and then reading the results
|
|||
|
backwards.
|
|||
|
|
|||
|
16 | 41713
|
|||
|
16 | 2607 r 1 (41713 / 16 = 2607 r 1)
|
|||
|
16 | 162 r F (2607 / 16 = 162 r 15)
|
|||
|
16 | 10 r 2 (162 / 16 = 10 r 2)
|
|||
|
| 0 r A (10 / 16 = 0 r 10)
|
|||
|
|
|||
|
Read the remainders bacckwards, our number is : A2F1 hex. Again, the same
|
|||
|
method can be used for binary.
|
|||
|
|
|||
|
The reason why hex is popular is obvious ... using bits, it is impossible
|
|||
|
to get a reasonable base 10 (decimal) system going, and binary get's unwieldly
|
|||
|
at high values. Don't worry too much though : most assemblers (like Tasm)
|
|||
|
will convert all your decimal values to hex for you.
|
|||
|
|
|||
|
You have four general purpose registers : AX, BX, CX and DX
|
|||
|
Think of them as variables that you will always have. On a 286, these
|
|||
|
registers are 16 bytes long, or one word.
|
|||
|
|
|||
|
As you know, a word consists of two bytes, and in assembler you can access
|
|||
|
these bytes individualy. They are separated into high bytes and low bytes per
|
|||
|
word.
|
|||
|
|
|||
|
High Byte | Low Byte
|
|||
|
0000 0000 | 0000 0000 bits
|
|||
|
[--------Word-------]
|
|||
|
|
|||
|
The method of access is easy. The high byte of AX is AH, and the low byte is
|
|||
|
AL ... you can also access BH, BL, CH, CL, DH and DL.
|
|||
|
|
|||
|
A 386 has extended registers : EAX, EBX, ECX, EDX ... you can access the
|
|||
|
lower word normally (as AX, with bytes AH and AL), but you cannot access the
|
|||
|
high word directly ... you must ror EAX,16 (rotate the binary value through
|
|||
|
16 bits), after which the high word and low word swap ... do it again to
|
|||
|
return them. Acessing EAX as a whole is no problem ... mov eax,10 ;
|
|||
|
add eax,ebx ... these are all vaild.
|
|||
|
|
|||
|
Next come segments. As you have probably heard, computer memory is divided
|
|||
|
into various 64k segments (note : 64k = 65536 bytes, sound familiar?) A
|
|||
|
segment register points to which segment you are looking at. An offset
|
|||
|
register points to how far into that segment you are looking. One way
|
|||
|
of looking at it is like looking at a 2d array ... the segments are your
|
|||
|
columns and your offsets are your rows. Segments and offsets are displayed
|
|||
|
as Segment:Offset ... so $a000:50 would mean the fiftieth byte in segment
|
|||
|
$a000.
|
|||
|
|
|||
|
The segment registers are ES, DS, SS and CS. A 386 also has FS an GS.
|
|||
|
These values are words (0-65535), and you cannot access the high or low bytes
|
|||
|
separately. CS points to you your code segment, and usually if you touch this
|
|||
|
your program will explode. SS points to your stack segment, again, this
|
|||
|
baby is dangerous. DS points to your data segment, and can be altered, if
|
|||
|
you put it back after you use it, and don't use any global variables while
|
|||
|
it is altered. ES is your extra segment, and you can do what you want with
|
|||
|
it.
|
|||
|
|
|||
|
The offset registers are DI, SI, IP, SP, BP. Offset registers are generally
|
|||
|
asscociated with specific segment registers, as follows :
|
|||
|
ES:DI DS:SI CS:IP SS:SP ... On a 286, BX can be used instead of the above
|
|||
|
offset registers, and on a 386, any register may be used. DS:BX is therefore
|
|||
|
valid.
|
|||
|
|
|||
|
If you create a global variable (let's say bob), when you access that
|
|||
|
variable, the compiler will actually look for it in the data segment.
|
|||
|
This means that the statement :
|
|||
|
|
|||
|
ax = bob
|
|||
|
could be
|
|||
|
ax = ds:[15]
|
|||
|
|
|||
|
A quick note : A value may be signed or unsigned. An unsigned word has a
|
|||
|
range from 0 to 65535. A signed word is called an integer and has a range
|
|||
|
-32768 to 32767. With a signed value, if the leftmost bit is equal to 1,
|
|||
|
the value is in the negative.
|
|||
|
|
|||
|
Next, let us have a look at the stack. Let us say that you want to save the
|
|||
|
value in ax, use ax to do other things, then restore it to it's origional
|
|||
|
value afterwards. This is done by utilising the stack. Have a look at the
|
|||
|
following code :
|
|||
|
|
|||
|
mov ax, 50 ; ax is equal to 50
|
|||
|
push ax ; push ax onto the stack
|
|||
|
mov ax, 27 ; ax is equal to 27
|
|||
|
pop ax ; pop ax off the stack
|
|||
|
At this point, ax is equal to 50.
|
|||
|
|
|||
|
Remember we defined the stack to be 200h further up? This is part of the
|
|||
|
reason we have it. When you push a value onto the stack, that value is
|
|||
|
recorded on the stack heap (referenced by SS:SP, SP is incremented) When you
|
|||
|
pop a value off the stack, the value is placed into the variable you are
|
|||
|
poping it back in to, SP is decremented and so forth. Note that the computer
|
|||
|
does not care what you pop the value back in to ...
|
|||
|
|
|||
|
mov ax, 50
|
|||
|
push ax
|
|||
|
pop bx
|
|||
|
|
|||
|
Would set the values of both ax and bx to 50. (there are faster ways of doing
|
|||
|
this, pushing and poping are fairly fast though)
|
|||
|
|
|||
|
push ax
|
|||
|
push bx
|
|||
|
pop ax
|
|||
|
pop bx
|
|||
|
|
|||
|
would swap the values of ax and bx. As you can see, to pop the values back
|
|||
|
in to the origional variables, you must pop them back in the opposite
|
|||
|
direction to which you pushed them.
|
|||
|
|
|||
|
push ax
|
|||
|
push bx
|
|||
|
push cx
|
|||
|
|
|||
|
pop cx
|
|||
|
pop bx
|
|||
|
pop ax
|
|||
|
|
|||
|
would result in no change for any of the registers.
|
|||
|
|
|||
|
When a procedure is called, all the parameters for that procedure are pushed
|
|||
|
onto the stack. These can actually be read right off the stack, if you want
|
|||
|
to.
|
|||
|
|
|||
|
As you have already seen, the mov command moves a value...
|
|||
|
|
|||
|
mov <dest>, <source>
|
|||
|
|
|||
|
Note that dest and source must be the same number of bits long...
|
|||
|
|
|||
|
mov ax, dl
|
|||
|
|
|||
|
would not work, and neither would
|
|||
|
|
|||
|
mov cl,bx
|
|||
|
|
|||
|
However, mov cx,dx
|
|||
|
mov ax,50
|
|||
|
mov es,ax
|
|||
|
are all valid.
|
|||
|
|
|||
|
Shl I have explained before, it is where all the bits in a register are
|
|||
|
shifted one to the left and a zero added on to the right. This is the
|
|||
|
eqivalent of multiplying the value by two. Shr works in the opposite
|
|||
|
direction.
|
|||
|
|
|||
|
Rol does the same, except that the bit that is removed from the left is
|
|||
|
replaced on the right hand side. Ror works in the opposite direction.
|
|||
|
|
|||
|
div <value> divides the value in ax by value and returns the result in
|
|||
|
al if value is a byte, placing the remainder in ah. If value is a word,
|
|||
|
the double word DX:AX is divided by value, the result being placed in ax
|
|||
|
and the remainder in dx. Note that this only works for unsigned values.
|
|||
|
|
|||
|
idiv <value> does the same as above, but for signed variables.
|
|||
|
|
|||
|
mul <value> If value is a byte, al is multiplied by value and the result
|
|||
|
is stored in ax. If value is a word, ax is multiplied by value and the
|
|||
|
result is stored in the double word DX:AX
|
|||
|
|
|||
|
imul <value> does the same as above, but for signed variables.
|
|||
|
|
|||
|
The j* commands are fairly simple : if a condition is met, jump to a certain
|
|||
|
lable.
|
|||
|
|
|||
|
jz <label> Jump if zero
|
|||
|
ja <label> Jump above (unsigned)
|
|||
|
jg <label> Jump greater (signed)
|
|||
|
|
|||
|
and so forth.
|
|||
|
|
|||
|
An example ...
|
|||
|
|
|||
|
cmp ax,50 ; Compare ax to 50
|
|||
|
je @Equal ; If they are equal, jump to label @equal
|
|||
|
|
|||
|
call MyProc Runs procedure MyProc and then returns to the next line of code.
|
|||
|
|
|||
|
Procedures are declared as follows :
|
|||
|
|
|||
|
MyProc proc near
|
|||
|
ret ; Must be here to return from where it was called
|
|||
|
MyProc endp
|
|||
|
|
|||
|
Variables are also easy :
|
|||
|
|
|||
|
bob db 50
|
|||
|
|
|||
|
creates a variable bob, a byte, with an initial value of 50.
|
|||
|
|
|||
|
bob2 dw 50
|
|||
|
|
|||
|
creates a variable bob2, a word, with an initial value of 50.
|
|||
|
|
|||
|
bob3 db 1,2,3,4,5,65,23
|
|||
|
|
|||
|
creates bob3, an array of 7 bytes.
|
|||
|
|
|||
|
bob4 db 100 dup (?)
|
|||
|
|
|||
|
creates bob4, an array of 100 bytes, with no starting value.
|
|||
|
|
|||
|
Go back and look at tut 7 for a whole lot more assembler commands, and get
|
|||
|
some sort of reference guide to help you out with others. I personally use
|
|||
|
the Norton Guides help file to program assembler.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Fire Routines
|
|||
|
|
|||
|
To demonstrate how to write an assembler program, we will write a fire
|
|||
|
routine in 100% assembler. The theory is simple...
|
|||
|
|
|||
|
Set the pallette to go from white to yellow to red to blue to black.
|
|||
|
Create a 2d array representing the screen on the computer.
|
|||
|
Place high values at the bottom of the array (screen)
|
|||
|
for each element, do the following :
|
|||
|
Take the average of the four elements under it
|
|||
|
|
|||
|
* Current element
|
|||
|
123
|
|||
|
4 Other elements
|
|||
|
Get the average of the four elements, and place the result in the current
|
|||
|
element.
|
|||
|
Repeat
|
|||
|
|
|||
|
Easy, no? I first saw a fire routine in the Iguana demo, and I just had to
|
|||
|
do one ;) ... it looks very effective.
|
|||
|
|
|||
|
With the sample file, I have created a batch file, make.bat ... it basically
|
|||
|
says :
|
|||
|
tasm fire
|
|||
|
tlink fire
|
|||
|
|
|||
|
So to build and run the fire program, type :
|
|||
|
make
|
|||
|
fire
|
|||
|
|
|||
|
The source file is commented quite well, so there shouldn't be any problems.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
As you can see, the sample program is in 100% assembler. For the next tut
|
|||
|
I will return to Pascal, and hopefully your new found assembler skills will
|
|||
|
help you there too.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Byeeeee....
|
|||
|
- Denthor
|
|||
|
|
|||
|
The following are official ASPHYXIA distribution sites :
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
|
|||
|
<EFBFBD>BBS Name <20>Telephone No. <20>Open <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD>ASPHYXIA BBS #1 <20>+27-31-765-5312 <20>ALL <20>
|
|||
|
<EFBFBD>ASPHYXIA BBS #2 <20>+27-31-765-6293 <20>ALL <20>
|
|||
|
<EFBFBD>C-Spam BBS <20>410-531-5886 <20>ALL <20>
|
|||
|
<EFBFBD>POP! <20>+27-12-661-1257 <20>ALL <20>
|
|||
|
<EFBFBD>Soul Asylum <20>+358-0-5055041 <20>ALL <20>
|
|||
|
<EFBFBD>Wasted Image <20>407-838-4525 <20>ALL <20>
|
|||
|
<EFBFBD>Reckless Life <20>351-01-716 67 58<35>ALL <20>
|
|||
|
<EFBFBD>Mach 5 BBS <20>+1 319-355-7336 <20>ALL <20>
|
|||
|
<EFBFBD>House of Horror <20>+1 513-734-6470 <20>ALL <20>
|
|||
|
<EFBFBD>Zero Level <20>+39 6-810-9934 <20>ALL <20>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
|
|||
|
|
|||
|
Leave me mail if you want to become an official Asphyxia BBS
|
|||
|
distribution site.
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 20 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Hi all! It has been a _long_ time since my last trainer (as I am sure many
|
|||
|
of you have noticed) A lot has happened between now and the last trainer...
|
|||
|
but for once I won't bore you with the details ;) I do have a full time job
|
|||
|
though, coding C++ applications.
|
|||
|
|
|||
|
I have taken over the production of the PCGPE from Mark Feldman. He is
|
|||
|
mailing all the articles written so far, and as soon as I get them I will
|
|||
|
get to work on releasing the PCGPE II. Mark is working on the Windows GPE.
|
|||
|
|
|||
|
This trainer is on 3d hidden face removal and face sorting. I was going to
|
|||
|
add shading, but that can wait until a later trainer. For conveniance I
|
|||
|
will build on the 3d code from tut 16(?). The maths for face removal is a
|
|||
|
bit tricky, but just think back to your old High School trig classes.
|
|||
|
|
|||
|
I have noticed that in my absence, one or two people have started their own
|
|||
|
trainer series. Read Hornet DemoNews for a great column by Trixter covering
|
|||
|
some of the more tricky demo effects.
|
|||
|
|
|||
|
Well, on with the trainer!
|
|||
|
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
|
|||
|
on the ASPHYXIA BBS.
|
|||
|
2) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
South Africa
|
|||
|
3) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
|
|||
|
call during varsity). Call +27-31-73-2129 if you call
|
|||
|
from outside South Africa. (It's YOUR phone bill ;-))
|
|||
|
4) Write to denthor@beastie.cs.und.ac.za in E-Mail.
|
|||
|
5) Write to asphyxia@beastie.cs.und.ac.za to get to all of
|
|||
|
us at once.
|
|||
|
|
|||
|
NB : If you are a representative of a company or BBS, and want ASPHYXIA
|
|||
|
to do you a demo, leave mail to me; we can discuss it.
|
|||
|
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
|
|||
|
quite lonely and want to meet/help out/exchange code with other demo
|
|||
|
groups. What do you have to lose? Leave a message here and we can work
|
|||
|
out how to transfer it. We really want to hear from you!
|
|||
|
|
|||
|
http://goth.vironix.co.za/~denthor (WWW)
|
|||
|
ftp.eng.ufl.edu pub/msdos/demos/code/graph/tutor (FTP)
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Face Sorting
|
|||
|
|
|||
|
There are many ways to sort faces in a 3d object. For now, I will show you
|
|||
|
just about the easiest one of the lot.
|
|||
|
|
|||
|
Say you have to polygons....
|
|||
|
|
|||
|
------P1
|
|||
|
|
|||
|
------------------P2
|
|||
|
|
|||
|
Eye
|
|||
|
|
|||
|
As you can see, P1 has to be drawn before P2. The easiest way to do this is
|
|||
|
as follows:
|
|||
|
|
|||
|
On startup, find the mid point of each of the polys, through the easy
|
|||
|
equations,
|
|||
|
x = (P2.1.x + P2.2.x + P2.3.x + p2.4.x)/4
|
|||
|
y = (P2.1.y + P2.2.y + P2.3.y + p2.4.y)/4
|
|||
|
z = (P2.1.z + P2.2.z + P2.3.z + p2.4.z)/4
|
|||
|
|
|||
|
NOTE : For a triangle you would obviously only use three points and divide
|
|||
|
by three.
|
|||
|
|
|||
|
Anyway, now you have the X,Y,Z of the midpoint of the polygon. You can then
|
|||
|
rotate this point with the others. When it comes time to draw, you can
|
|||
|
compare the resulting Z of the midpoint, sort all of the Z items, and then
|
|||
|
draw them from back to front.
|
|||
|
|
|||
|
In the sample program I use a simple bubble sort... basically, I check the
|
|||
|
first two values against each other, and swap them if the first is bigger
|
|||
|
then the second. I continue doing this to all the numbers until I run
|
|||
|
through the entire list without swapping once. Bubble sorts are standard
|
|||
|
seven computer science topics... perhaps borrow a text book to find out
|
|||
|
more about them and other (better) sorting methods.
|
|||
|
|
|||
|
The above isn't perfect, but it should work 90% of the time. But it still
|
|||
|
means that when you are drawing a cube, you have to draw all 6 sides every
|
|||
|
frame, even though only three or so are visible. That is where hidden face
|
|||
|
removal comes in...
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Hidden Face Removal
|
|||
|
|
|||
|
Pick up something square. A stiffy disk will do fine. Face it towards you,
|
|||
|
and number all the corners from one to four in a clockwise direction.
|
|||
|
|
|||
|
1 +-------------+ 2
|
|||
|
| |
|
|||
|
| |
|
|||
|
| |
|
|||
|
| |
|
|||
|
4 +-------------+ 3
|
|||
|
|
|||
|
Now rotate the stiffy disk on all three axese, making sure that you can
|
|||
|
still see the front of the disk. You will notice that whenever you can see
|
|||
|
the front of the disk, the four points are still in alphabetical order. Now
|
|||
|
rotate it so that you can see the back of the stiffy. Your points will now
|
|||
|
be :
|
|||
|
|
|||
|
2 +-------------+ 1
|
|||
|
| |
|
|||
|
| |
|
|||
|
| |
|
|||
|
| |
|
|||
|
3 +-------------+ 4
|
|||
|
|
|||
|
The points are now anti-clockwise! This means, in it's simplest form, that
|
|||
|
if you define all your poygon points in a clockwise order, when drawing you
|
|||
|
ignore the polys that are anticlockwise. (Obviously when you define the 3d
|
|||
|
object, you define the polygons facing away from you in an anticlockwise
|
|||
|
order)
|
|||
|
|
|||
|
To find out weather a poly's points are clockwise or not, we need to find
|
|||
|
it's normal. Here is where things start getting fun.
|
|||
|
|
|||
|
In school, you are told that a normal is perpendicular to the plane. In
|
|||
|
ascii :
|
|||
|
| Normal
|
|||
|
|
|
|||
|
|
|
|||
|
--------------------------- Polygon
|
|||
|
|
|||
|
As you can see, the normal is at 90 degrees to the surface of the poly. We
|
|||
|
must extend this to three dimensions for our polygons. You'll have to trust
|
|||
|
me on that, I can't draw it in ascii :)
|
|||
|
|
|||
|
To find a normal, you only need three points from your poly (ABC) :
|
|||
|
A(x0,y0,z0), B(X1,Y1,Z1), C(X2,Y2,Z2)
|
|||
|
|
|||
|
then the vector normal = AB^AC = (Xn,Yn,Zn) with
|
|||
|
Xn=(y1-y0)(z0-z2)-(z1-z0)(y0-y2)
|
|||
|
Yn=(z1-z0)(x0-x2)-(x1-x0)(z0-z2)
|
|||
|
Zn=(x1-x0)(y0-y2)-(y1-y0)(x0-x2)
|
|||
|
|
|||
|
We are interested in the Z normal, so we will use the function :
|
|||
|
normal:=(x1-x0)(y0-y2)-(y1-y0)(x0-x2);
|
|||
|
|
|||
|
The result is something of a sine wave when you rotate the poly in three
|
|||
|
dimensions. A negative value means that the poly is facing you, a posotive
|
|||
|
value means that it is pointing away.
|
|||
|
|
|||
|
The above means that with a mere two muls you can discount an entire poly
|
|||
|
and not draw it. This method is perfect for "closed" objects such as cubes
|
|||
|
etc.
|
|||
|
|
|||
|
I am anything but a maths teacher, so go borrow someones math book to find
|
|||
|
out more about surface normals. Trust me, there is a lot more written about
|
|||
|
them then you think.
|
|||
|
|
|||
|
An extension of calculating your normal is finding out about light-sourcing
|
|||
|
your polygons. Watch for more information in one of the next few tutors.
|
|||
|
|
|||
|
|
|||
|
A combination of the above two routines should work quite nicely in
|
|||
|
creating 3d objects with little or no overlapping. The example file will
|
|||
|
show you the two methods and how well they work.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
As you can see, the above was quite easy. I have a few ideas for tut 21, so
|
|||
|
keep watch for it. Also keep an eye open for PCGPE ][ (but don't mail me
|
|||
|
asking when it's due! I already get too many of those! ;-)
|
|||
|
|
|||
|
My sister got married a few days ago. The worst part was that I was forced
|
|||
|
to cut my hair. My hair was quite long (slightly longer then when the pic
|
|||
|
on my web page was taken), and it is all quite depressing. Anyway, the
|
|||
|
wedding was great, so it wasn't all for nothing.
|
|||
|
|
|||
|
I hope to get tut 21 and possibly 22 out before christmas, but I will be on
|
|||
|
holiday from the 18th. I will be in Cape Town sometime after christmas day
|
|||
|
for a week or two, so if you're there I'll meet you on the cable car :-)
|
|||
|
|
|||
|
I wrote a quote for this tut, but I have decided I didn't like it. I'll try
|
|||
|
do better for tut 21 ;)
|
|||
|
|
|||
|
Byeeeee.....
|
|||
|
- Denthor
|
|||
|
14-12-95
|
|||
|
|
|||
|
PS. I seem to have lost my list of distribution sites... could you all
|
|||
|
re-mail me your details? Thanks.
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20> W E L C O M E <20>
|
|||
|
<20> To the VGA Trainer Program <20> <20>
|
|||
|
<20> By <20> <20>
|
|||
|
<20> DENTHOR of ASPHYXIA <20> <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
--==[ PART 21 ]==--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Introduction
|
|||
|
|
|||
|
Hi there! It's been quite a long time (again) since the last tutorial ...
|
|||
|
I'll bet some of you had given up one me ;-)
|
|||
|
|
|||
|
Today is my 21st birthday, so I decided it would be the perfect time to
|
|||
|
finish up this trainer which I have been meaning to send out for weeks.
|
|||
|
It's on texure mapping. I know, I know, I said light sourcing, then gourad,
|
|||
|
then texture mapping, but I got enough mail (a deluge in fact ;) telling me
|
|||
|
to do texure mapping...
|
|||
|
|
|||
|
I'll be using the code from Tut 20 quite extensively, so make sure you know
|
|||
|
whats going on in there... well, on with the show!
|
|||
|
|
|||
|
BTW, I've improved my web page quite a bit... give it a visit, I want to
|
|||
|
really ramp up that hit count :)
|
|||
|
|
|||
|
If you would like to contact me, or the team, there are many ways you
|
|||
|
can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
|
|||
|
on the ASPHYXIA BBS.
|
|||
|
2) Write to : Grant Smith
|
|||
|
P.O.Box 270 Kloof
|
|||
|
3640
|
|||
|
Natal
|
|||
|
South Africa
|
|||
|
3) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
|
|||
|
call during work hours). Call +27-31-73-2129 if you call
|
|||
|
from outside South Africa. (It's YOUR phone bill ;-))
|
|||
|
4) Write to denthor@goth.vironix.co.za in E-Mail.
|
|||
|
5) Write to asphyxia@beastie.cs.und.ac.za to get to all of
|
|||
|
us at once.
|
|||
|
|
|||
|
http://www.vironix.co.za/~grants (WWW)
|
|||
|
ftp.eng.ufl.edu pub/msdos/demos/code/graph/tutor (FTP)
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> Free Direction Texture Mapping
|
|||
|
|
|||
|
There are two things you should know before we begin.
|
|||
|
|
|||
|
Firstly, I am cheating. The texture mapping I am going to show you is not
|
|||
|
perspective-correct, with clever divides for z-placement etc. This method
|
|||
|
looks almost as good and is quite a bit faster too.
|
|||
|
|
|||
|
Secondly, you will find it all rather easy. The reason for this is that it's
|
|||
|
all rather simple. I first made the routine by sitting down with some paper
|
|||
|
and a pencil and had it on the machine in a few hours. A while later when
|
|||
|
people on the net started discussing their methods, they were remarkably
|
|||
|
similar.
|
|||
|
|
|||
|
Let me show you what I mean.
|
|||
|
|
|||
|
Let us assume you have a texture of 128x128 (a straight array of bytes
|
|||
|
[0..127, 0..127]) which you want to map onto the side of a polygon. The
|
|||
|
problem of course being that the polygon can be all over the place, with
|
|||
|
one side longer then the other etc.
|
|||
|
|
|||
|
Our first step is to make sure we know which end is up... let me
|
|||
|
demonstrate...
|
|||
|
1
|
|||
|
+
|
|||
|
/ \
|
|||
|
/ \
|
|||
|
4 + + 2
|
|||
|
\ /
|
|||
|
\ /
|
|||
|
+
|
|||
|
3
|
|||
|
|
|||
|
Let us say that the above is the chosen polygon. We have decided that point
|
|||
|
1 is the top left, point 3 is bottom right. This means that
|
|||
|
1 - 2 is the top of the texture
|
|||
|
2 - 3 is the right of the texture
|
|||
|
3 - 4 is the bottom of the texture
|
|||
|
4 - 1 is the left of the texture
|
|||
|
|
|||
|
The same polygon, but rotated :
|
|||
|
|
|||
|
3
|
|||
|
+
|
|||
|
/ \
|
|||
|
/ \
|
|||
|
2 + + 4
|
|||
|
\ /
|
|||
|
\ /
|
|||
|
+
|
|||
|
1
|
|||
|
|
|||
|
Although the positions of the points are different, point 1 is still the
|
|||
|
top left of our texture.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> How to put it to screen
|
|||
|
|
|||
|
Okay, so now you have four points and know which one of them is also the top
|
|||
|
left of our texture. What next?
|
|||
|
|
|||
|
If you think back to our tutorial on polygons, you will remember we draw it
|
|||
|
scanline by scanline. We do texture mapping the same way.
|
|||
|
|
|||
|
Lets look at that picture again :
|
|||
|
|
|||
|
1
|
|||
|
+
|
|||
|
a / \ b
|
|||
|
/ \
|
|||
|
4 + + 2
|
|||
|
\ /
|
|||
|
\ /
|
|||
|
+
|
|||
|
3
|
|||
|
|
|||
|
We know that point 1 is at [0,0] in our texture. Point 2 is at [127,0],
|
|||
|
Point 3 is at [127,127], and Point 4 is at [0,127].
|
|||
|
|
|||
|
The clever bit, and the entire key to texture mapping, is making the
|
|||
|
logical leap that precisely half way between Point 1 and Point 2 (b), we are at
|
|||
|
[64,0] in our texture. (a) is in the same manner at [0,64].
|
|||
|
|
|||
|
That's it. All we need to know per y scanline is :
|
|||
|
The starting position on the x axis of the polgon line
|
|||
|
The position on the x in the texture map referenced by that point
|
|||
|
The position on the y in the texture map referenced by that point
|
|||
|
|
|||
|
The ending position on the x axis of the polgon line
|
|||
|
The position on the x in the texture map referenced by that point
|
|||
|
The position on the y in the texture map referenced by that point
|
|||
|
|
|||
|
Let me give you an example. Let's sat that (a) and (b) from the above
|
|||
|
picture are on the same y scanline. We know that the x of that scanline is
|
|||
|
(say) 100 pixels at the start and 200 pixels at the end, making it's width
|
|||
|
100 pixels.
|
|||
|
|
|||
|
We know that on the left hand side, the texture is at [0,64], and at the
|
|||
|
right hand side, the texture is at [64,0]. In 100 pixels we have to
|
|||
|
traverse our texture from [0,64] to [64,0].
|
|||
|
|
|||
|
Assume at the start we have figured out the starting and ending points in
|
|||
|
the texture
|
|||
|
textureX = 0;
|
|||
|
textureY = 64;
|
|||
|
textureEndX = 64;
|
|||
|
textureEndY = 0;
|
|||
|
|
|||
|
dx := (TextureEndX-TextureX)/(maxx-minx);
|
|||
|
dy := (TextureEndY-TextureY)/(maxx-minx);
|
|||
|
for loop1 := minx to maxx do BEGIN
|
|||
|
PutPixel (loop1, ypos, texture [textureX, textureY], VGA);
|
|||
|
textureX = textureX + dx;
|
|||
|
textureY = textureY + dy;
|
|||
|
END;
|
|||
|
|
|||
|
|
|||
|
Do the above for all the scanlines, and you have a texture mapped polygon!
|
|||
|
It's that simple.
|
|||
|
|
|||
|
We find our beginning and ending positions in the usual fasion. We know
|
|||
|
that Point 1 is [0,0]. We know that Point 2 is [127,0]. We know the number
|
|||
|
of scanlines on the y axis between Point 1 and Point 2.
|
|||
|
|
|||
|
textureDX = 127/abs (point2.y - point1.y)
|
|||
|
|
|||
|
We run though all the y scanlines, starting from [0,0] and adding the above
|
|||
|
formula to the X every time. When we hit the last scanline, we will be at
|
|||
|
point [127,0] in the texure.
|
|||
|
|
|||
|
Repeat for all four sides, and you have the six needed variables per
|
|||
|
scanline.
|
|||
|
|
|||
|
|
|||
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|||
|
<EFBFBD> In closing
|
|||
|
|
|||
|
As you can see, texture mapping (this type at least) is quite easy, and
|
|||
|
produces quite a good result. You will however notice a bit of distortion
|
|||
|
if you bring the polygon too close. This can be fixed by a) Subdividing the
|
|||
|
polygon, so the one is made up of four or more smaller polygons. Much
|
|||
|
bigger, but works; b) Using more accurate fixed point; or c) Figuring out
|
|||
|
perspective correct texture mapping, mapping along constant-z lines etc.
|
|||
|
|
|||
|
When people write me, they often refer to my "tutes". This stems back to
|
|||
|
Mark Feldman calling them such in the PCGPE. I always though a "tute" was
|
|||
|
something you did with your car to gain someones attention. I dunno, maybe
|
|||
|
its an Australian thing ;-)
|
|||
|
|
|||
|
I have been coding almost exclusively in C/C++ for the past year or so.
|
|||
|
Sorry guys, thats all they will pay me for ;) Anyway, the trainers will
|
|||
|
continue to be in Pascal for ease of understanding by beginners, but if
|
|||
|
someone (*ahem* Snowman) doesn't start converting them to C soon, I will do
|
|||
|
it myself. He also corrected any mistakes I made while he was converting,
|
|||
|
so I'd prefer he did it (sort of a proofreader after release...)
|
|||
|
|
|||
|
Send me presents! It's my birthday!
|
|||
|
|
|||
|
Byeeeee.....
|
|||
|
- Denthor
|
|||
|
16-04-96
|
|||
|
|