Вы находитесь на странице: 1из 6


� �
� ***** FadeCode ***** �
� �
� By Esak (Aug 19, 1994) �

A sad legal ***p

I make no warranty whatsoever regarding this product. I assume no

responsiblity for any malicious impact on you, your computer, your red
blood cell production, or the sanity of the presidential candidate you
supported during the last election, made by the use or misuse of this

Hi there,

I decided to release the code for a number of different palette effects.

I will be the first to admit that it's not a Future Crew demo source code,
or anything vaguely close to earth-shattering. But I belive this release may
be useful to some beginning programmers. Learn from it if you can. Rip this
off if you want. You may even include source in your own library as long as
your library is a freeware as well. I won't ask for any credit. I am not
overly proud for this release anyway. But if you find this useful, a
postcard would be nice, though.

FADE_C.C It contains higher level interface routines which calls
some of the routines included in FADE.ASM.
FADE.ASM This is the main module that contains a bunch of
palette manipulating routines.
*.OBJ OBJ files. Compiled for large model.
MODEL.INC Include file for FADE.ASM
Change this if you would like to compile under a
different memory model.
FADE.H Header file for C

FADEDEMO.C A sample program demonstrating the use of the included

functions. Link with FADE_C.C and FADE.ASM.
FADEDEMO.PRJ Project file I used to link this program.
FADEDEMO.EXE The executable.

SCREEN.RAW 320*200 raw image file used by FADEDEMO

PAL1.pal palette file used by FADEDEMO
PAL2.pal palette file used by FADEDEMO

READMEOR.ELS You are reading this.

README.1st You read it before.
A quick intro to VGA palette format (For a newbie)
You (hopefully) know a VGA card can use 256 color at once. A VGA card
needs three bytes of information for each color. One byte for red
intensity. One byte for green intensity. And one byte for blue intensity.
So data for a complete 256 color VGA color palette amounts to 768 bytes
However, only six bit from each byte is used. So each byte can have a
value between 0..63.
Well, that's all I can and need to tell you now.

Bresenham Algorithm
One of the tricky problems that arise as you program palette fading is:

Simulating fade in etc, requires smooth transition from one color to

another. I have seen someone using floating point math to do this. For
graphic coders, floating point math is an evil that must be avoided.
So what's the solution? The famous/infamous Bresenham Algorithm. This
is commonly known as line algorithm, but this algorithm pops up almost
every corner in graphics programming world.
Let's say you need to change the value of a byte from 2 to 23. And you must
do changing 32 times. With floating math, it would be

loop 32 times begin
loop end

However, using Bresenham algorithm, it would be:

loop 32 times begin
if Decision_variable<32
loop end

It may look more complicated. But using B-algorithm is a LOT faster than
using floating point math. But as you can see, we need one more decision
variable for each variable we want to change. Therefore, many of the routines
here use additional 768 bytes to implement smooth color transition.

Functions in FADE_C.C
void fade_screen(void far *pal)
>it calls fade_once() 32 times.
>the content of the palette array is not preserved.

void fade_in_screen(void far *pal)

>it calls fade_in_once() 32 times.
>the content of the palette array is preserved.

void bright_screen(void far *pal)

>it calls bright_once() 32 times
>the content of the palette array is not preserved.

void bright_in_screen(void far *pal)

>it calls bright_in_once() 32 times
>the content of the palette array is preserved.

void fade_between_screen(void far *pal,void far *pal_dest)

>It call fade_between_once() 64 times
>pal[] and pal_dest[] both have to be 768 bytes (chars) long
>The content of neither palette array is preserved. However, the
content of pal_dest[] will be moved to pal[].

Please look at FADEDEMO.C to get a better idea of how to use the routines
in FADE_C.C.

Functions in FADE.ASM

void setPal(void far *pal)

>*pal points to an array of 768 bytes (chars) that contains

void fill_pal(void far *pal,char red, char green,char blue);

>Fills the palette array with the given color information

void copy_pal(void far *pal,void far *pal_dest);

>Copies one palette to another

void rotate_pal(void far *pal,char index,char numCol, char displacement);

>Note this carefully.
>This routine DOES preserve the content of pal[]
>Let me give you some examples to explain how this routine works.

This routine will update palette number from 63-95.
But no rotation will take place

This routine will also update palette number from 63-95.
But this time, the color #64 will replace the content of color #63
and color #65 will replace #66 etc.

void sub_palette(void far *pal,void far *pal_dest);

>Subtracts one palette from another. You have to call this function
>before calling fade_between_once() If you are not going to call
>fade_between_once() directly, you have no business calling this

In most cases, you WON'T have to call the following functions.

I will explain when you have to use these functions. Please look at
FADE_C.C. That would be the best way to learn how to use the following

void fade_out_once(void far *pal)

>Changes the content of the palette array
>Should be called 32 times to turn the screen completely black.

void bright_out_once(void far *pal)


void fade_in_once(void far *pal,void far *pal_dest)

>*pal shoul point to an array of 768*2 *BLANK* chars, not 768 chars.
>The second half of pal[768*2] will be used as decision variables
for Bresenham algorithm.
>After calling it 32 times, the content of pal[] will be identical
to the content of pal_dest[]

void fade_between_once(void far *pal,void far *pal_dest)

>sub_palette() must be called before calling this function.
>*pal shoul point to an array of 768*2 chars, not 768 chars.
>The second half of pal[768*2] will be used as decision variables
for Bresenham algorithm.
>After calling it 32 times, the content of pal[] will be identical
to the content of pal_dest[]

You have to use a *something*_once() routines when you want to

update palette while animating at the same time. What you do is something
like this:

while (not_finished)

What's to be done.
First of all, all of the routines included in this file change entire
256 color palette. I didn't write routines which can be used to change
a portion of palette. For most applications, you won't have to. (Especially
since these routine run snow-free on every machine I tested so far.)
But if you need to, I will leave this task for asn exercize for you. If
you are a half-way descent ASM programmer, it wouldn't be hard.
Beside, that's what source code is for: to modify. Well, I admit that my
assembly routines could use more documentation, though.
If anyone ports these codes to 32bit Pmode, please let me know.

To fellow coders

I have a very fast local bus VGA card. This toy allowed me to play _Strike
Commander_ on my 486/25. The problem is that many games demos exhibit
intolerable amount of snow when they change palette.

I see strong evidences that many programmers are still sending palette data
byte by byte. (out dx,al) I use this command instead.

rep outsb

This rep outsb command format has been around since 80286 came out. For
Christssake, use it!
I update 128 colors (384 bytes) at once and I get no snow on my video card.
(Updating 256 color at once gave me little snow, though.)

I am getting sick and tired of seeing snow on so many games and demos (Except
for some exceptions like _Zone66_.) If you don't want to use my routine for
palette fading, at least use rep outsb for updating palette.

About me
I am a first year computer engineering student (will be a sophomore in
a couple of weeks) attending Carnegie Mellon University, Pittsburgh,
Pennsylvania, USA, North America, Earth, Solar System, Milky Way..
(DAMN, I hate that joke. But this stupid joke always keeps coming back to
my mind..)

Uh well. Anyways, the surest and fastest way to reach me would be through the
My internet e-mail address is:

Let me know if you have any problems, questions, comments, etc. I will
do my best to reply, but don't get upset if you don't get any. Flames,
outrageous requests, and questions like "I don't know C. What can I do?"
etc, will most likely be ignored. If you need a coder or an artist, don't
hesistate to contact me, especially if it's a paying job. |-)

If you don't have an internet account, or would like to send me a postcard,

a Lamborghini, a chunk of fissionable material, or an alien facehugger, use
the following address. (Valid for 1994-95 school year)


Box No. 1504

The alternate mailing address follows. It's the address of my uncle and
aunt's home.
Just make sure you use my real name (Hyun Yim) so they can forward the mails

37 Blanan Drive
Chicopee, MA 01020-4803

Excuse any spelling or grammatical or logical errors.

English is not my first language and it's hard to think clearly at 5:00AM.

Thanks to Draeden of VLA. I didn't use his routines. But his palette
rotation code gave me the idea to code my own.

What else... oh yeah, I used TC++3.0 and TASM 4.0. Use /m2 option when
compiling with TASM.

Well, that's it for now. Watch out for my first game which will be released
sometime before the end of this millenium.

Esak (aka Hyun Yim aka Attila the Hyun)


My friends are toys. I make them.

- JF Sebastian, from _BladeRunner_

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, aka DENTHOR of Asphyxia