







                             Ultra VGA Engine 32
                                Version 1.38



                                      
                        (c)1996 Constantine Prouskas
                            InterAction software








                                      
Prologue                                                               2
Quickstart                                                             2
Requirements                                                           2
What's UVE32?                                                          2
License Agreement                                                      3
Technical Information                                                  4
UVE Theory                                                             5
 Frames                                                               5
 Pages                                                                6
  The VGA page                                                        6
  The Hidden page                                                     6
  The Background page                                                 6
  The Tiles page                                                      6
 Sprites                                                              7
  Loading sprite images                                               7
  Displaying a sprite                                                 8
  Sprite Chaining                                                     9
  Moving sprites                                                     10
  Sprite collision                                                   10
  Deleting sprites & images                                          10
  Other sprite attributes                                            11
 Palettes                                                            11
 Palette maps                                                        12
 Tiles                                                               12
 PCXs                                                                13
 Fonts                                                               13
 FLIs                                                                14
 WAD files                                                           15
UVE Interface                                                         15
 Unit interface section                                              15
 Other variables                                                     16
 Functions & Procedures                                              16
  General Purpose Commands                                           17
  Beginner Commands                                                  18
  Intermediate Commands                                              20
  Advanced Commands                                                  25
Supporting Utilities                                                  29
 UVSINFO                                                             29
 PCX2UVS                                                             29
 PCX2UVT                                                             29
 LIBMAKER                                                            29
Known bugs... err.. features                                          30
UVE32 Frequently Asked Questions                                      30
Contacting InterAction software                                       30
Registering                                                           31
Epilogue                                                             31


Prologue

Right off the bat, I'd like to clear up some things:

    Version 1.38 is the first public release of UVE32 and, as such, is
 prone to various bugs and errors.  I've been using UVE32 for more than two
 years now and everything is pretty much ironed out, but I wrote it, and I'm
 sure someone out there will try something I had never thought of and crash
 it.  So, if you encounter any bugs, please report them to me and I will
 correct them in the next release.  Read the section on contacting
 InterAction software for further info.

    UVE32 is shareware.  Try before you buy.  And we all know what that
 means.  If you like UVE32 and continue to use it, you must register it.
 Registering not only clears your conscience, but also entitles you to free
 updates, loads of utilities and support.  Read the section on registering
 for more information.




Quickstart

For those of you who are really, really in a hurry, take these steps to get
you started:

    Unzip UVE32.
    Run BENCH.EXE to see if your VGA is fast enough for UVE32 animation.
    Run UVEDEMO.EXE for an example of UVE32's capabilities.
    Load up Pascal and run the examples provided.
    Off you go!



Requirements

What you need to run UVE32:
    A computer.  I guess you have one of those already.  Must be at least a
 386, though, because of the 32-bit code.  Not much of a limitation, if you
 ask me.
    A VGA card.  The faster the better.
    Turbo Pascal v6.0 or Borland/Turbo Pascal v7.0.

That's it.




What's UVE32?

Let's start with the easy stuff.  UVE32 is a sprite-based graphics &
animation unit for Turbo Pascal 6.0 & Borland/Turbo Pascal 7.0.  Drop to DOS
and run BENCH.EXE and UVEDEMO.EXE to see an example of  what this baby can
do.

UVE32 stands for Ultra VGA Engine 32-bit.  Ultra is there to distinguish
UVE32 from the VGA Engine series, which is a set of three older libraries
(VENGINE, VENGINE2 and VENGINE3).  UVE32 has been rewritten from scratch,
using a different animation algorithm.  VGA because UVE32 supports only the
VGA (CGA support is on the way ;-).  Engine because it provides the
horsepower for an animation-intensive application, i.e. (who am I trying to
fool) GAMES. 32 because it contains 32-bit code and is capable of running in
protected mode. For the time being, 32 bit code is more or less useless
because of Borland's 16-bit compiler, but is included for when a decent 32-
bit compiler is released.

Here's a quick run-down of UVE32's features before we get started.

    runs in VGA 320x200 256 colors
    500 simultaneously active sprites
    32K maximum sprite dimension (width/height)
    64K maximum single sprite size
    sprite chaining
    sprite collision detection
    automatic memory management
    virtual coordinates in the -32K...+32K range
    animation window
    14 loadable fonts
    static or scrolling background
    transparency
    translucency
    palette maps
    palette cross-fades
    PCX support
    FLI support
    WAD file support

In my experience, sprite libraries can be divided into the following
categories:

    Easy to use (i.e., slow)
    Powerful (i.e., extremely user-unfriendly)
    Fast and user friendly (and written in C)

UVE32 offers an easy to use interface as well as low-level routines for
squeezing out that last bit of potential.  If you are a beginner, you will
find the interface very simple to use.  If you are more advanced, you will
not be held back by the inherent limitations that inevitably come with easy
user interfaces.

UVE32 might not run well on your system, depending on your VGA card.  If you
are one of those people that read the documentation before running every
executable in sight (fat chance), I suggest you drop to DOS and run the
demonstration and the benchmarking program to discover if everything runs as
expected.  Unless your VGA is a painfully slow one, however, I don't expect
you will run into any difficulties.

Before we get into the intricacies of UVE32, take a moment to read the
License Agreement, which contains some important information concerning the
use of  UVE32.




License Agreement

InterAction software grants you the right to use Ultra VGA Engine 32
("UVE32").  For purposes of this section, "use" means loading UVE32 into
RAM, as well as installation on a hard disk or other storage  device.

You may use the shareware version of UVE32 for a period of 21 days, after
which you must either delete it or obtain the registered version.

You may freely distribute, transmit and store the shareware version of UVE32
on any electronic media, including but not limited to floppy diskette, hard
disk, CD-ROM or other storage device, provided that you do not remove, edit,
modify, or otherwise alter the original files of UVE32.  You may not
distribute the registered version of UVE32.

You may not modify, translate, disassemble, decompile, reverse engineer or
create derivative works (excluding software that uses UVE32 directly) based
upon UVE32.

You may use UVE32 in your own software, provided that you have complied with
the registration requirements set forth by InterAction software.  You may
not use the shareware version of UVE32 in any piece of software that will
become publicly available, including but not limited to public domain,
freeware, shareware and commercial/retail software.

UVE32 is copyrighted by InterAction software and is protected by
international copyright laws and international treaty provisions.  You must
treat UVE32 like any other copyrighted material.  You
agree to use your best efforts to see that any user of UVE32 licensed
hereunder complies with this agreement.

This software and accompanying written materials (including instructions for
use) are provides "as is" without warranty of any kind. Further, InterAction
software does not warrant or make any guarantees representations regarding
the use, or the results of use, of the software or written materials in
terms of correctness, accuracy, reliability, currentness, or otherwise. The
entire risk as to the results and performance of the software is assumed by
you.

The above is the only warranty of any kind, either expressed or implied,
including but not limited to, implied warranties of merchantability or
fitness for a particular purpose.  In any case, InterAction software shall
not be liable for any direct, indirect, consequential or incidental damages
(including damages for loss of business profits, business interruption, loss
of business information and loss of data) arising out of the use or
inability to use UVE32, even if InterAction software has been advised of the
possibility of such damages.

You acknowledge that you have read this agreement, you understand this
agreement, and understand that by continuing the installation of UVE32, by
loading or running UVE32, or by placing or copying UVE32 onto your computer
hard drive, you agree to be bound by this agreement's terms and conditions.




Technical Information

NO!  NO!  NO!  I said READ the License Agreement, not SKIP OVER it!  As
boring as it sounds, you must read it before using UVE32.  You have?  That's
OK, then.  Let's get moving.

Note:  This section contains, as the heading would suggest,  technical
information.  You do not need to know anything contained in this section to
use UVE32.  Instead, it's meant to provide some insight at how UVE32 works.
If you haven't got any experience with the VGA and the VGA hardware, it's
best to skip this section altogether.

UVE32 runs in the standard VGA mode 0x13 (19 to you ten-fingered people).
That's your average 320x200 256-color mode supported by the BIOS in every
VGA since, well, the EGA.  Okay, so it's only got one page and an odd aspect-
ratio, but when it comes to rock-solid animation and simple code (the latter
bearing the most weight for me personally), the fact is, you can't beat mode
0x13's non-banked linear bitmap organization.

UVE32 is based on a, for lack of a better term, page-copy algorithm.  To
those of you familiar with dirty-rectangle animation, you can think of the
whole screen as being a single dirty rectangle, updated each frame.  What
does this mean?  It means that all preparation for a frame is done in non-
displayable system memory area the same size as the screen (a "page").  Once
the whole frame is complete, the "hidden" page is simply copied onto the
visible screen.  You might think copying the whole screen every frame is
overkill; and you'd be right (didn't expect me to say that, did you?), but
only in light load conditions.  In heavy load conditions and in cases where
the whole screen changes from frame to frame (such as in panning around a
virtual background), this is much faster than trying to maintain a list of
updated areas and optimizing it so that each pixel is drawn once and only
once.

I'd like to take a moment to point out that when I came up with this sort of
algorithm, I didn't have a clue about page-flipping (or any other animation
technique, for that matter), and it seemed like the intuitive thing to do.
I have to admit, though, that, even now, I would be hard pressed to find
another algorithm that can deliver flawless frames given an adequately fast
VGA.  Also, a little known fact is that page-flipped modes are built around
the VGA's vertical sync/retrace signal, which cannot be relied upon, because
there is no specification about exactly when it should occur.  Some of the
other page-flipped libraries around flickered hideously when I ran them on
my computer.

All drawing is done in system memory, which is much faster that video
memory.  Since the image has to be copied to video memory in the end,
however, video memory speed becomes the ultimate bottleneck, and, believe
me, a narrow bottleneck it is.  On my slow ISA VGA, video access takes 50%
of a 50-ms frame.  It can get much worse than this, though.  Some VGAs in my
university lab (no names, please) take more than 500ms to copy the page onto
display memory.  FIVE HUNDRED milliseconds for a maximum of under 2 frames
per second!  You need not worry if you have a local bus VGA, however, and
I've found that all Trident-based cards I've tested peak at about 20fps,
which btw is fine for animation.  On a typical 486-33 with a local bus VGA,
a sustained rate of 35-40 frames per second is not extraordinary.

Apart from the VGA access time bottleneck, another potential problem is
shearing.  Shearing occurs when the VGA is scanning displayable data while
the CPU is copying from the hidden page to the visible page.  Let's just say
for a second that the CPU cannot copy data as fast as the electron beam
sweeps the screen (usually 70Hz).  Let's also assume that the electron beam
starts scanning when the CPU is halfway through copying data, and that it
catches up with the CPU at some point within the displayable data area.
Everything displayed up to that point will belong to the new frame, and
everything below will belong to the old frame, since the CPU hasn't had a
chance to update it yet. The result will be a frame composed of parts of two
different frames.

Shearing is bad, but not as bad as you might think.  It is only noticeable
on a slow VGA, with a continuously scrolling background of specific pattern
types and even then, it registers as some sort of flicker (not the type
you're used to, just some sort of color dimming at specific scanlines of the
screen).  Shearing is inherent to beam scanning anyway, since the screen is
not updated all at the same instant.  If your VGA is capable of copying the
whole page in the 70Hz time window, then shearing should not pose a problem.
In my experience, you can only see it when a disk caching program kicks in
and writes to disk during the memory move (btw, in UVE32, interrupts are not
disabled during a memory move).




UVE Theory


Frames

Note:  This section, despite being the basis of everything else, contains a
lot of forward references.  If you don't understand what's going on, simply
go on and come back once you've read the rest of the UVE32 theory.

Frames are the building blocks of animation.  They are the same type of
frames used in traditional cinema and television animation.  A typical UVE32
frame cycle goes as follows:
    First, the background is copied onto the workarea (the hidden page),
  erasing everything from the previous frame.
    The scrolling background, if enabled, is constructed and placed on top
  of the background.
    The sprites are copied, with sprite 500 going first and sprite 1 last.
  This means that, as viewed on the screen, sprite 1 is on top and sprite 500
  is at the very bottom.
    The frame is now complete and is made visible on the screen.
    If there is still time, UVE32 waits until the extra time expires before
starting on the next frame.

I didn't know when I first built UVE32, but the same frame technique is used
by Mortal Kombat and Quake (in videomode 0).  It's the most efficient way to
do animation when the whole screen changes from frame to frame.  If you know
of any more games that use this technique, I'd like to hear from you.

Related functions:
procedure ia_waitretrace;
procedure ia_doframepart1;
procedure ia_doframepart2;
procedure ia_doframepart3;
procedure ia_doframe;
procedure ia_setcycletime (i:integer);



Pages

A page is simply a region of memory that can hold a 320x200 image (actually
it's a bit more that that, but who's counting).  UVE32 has 4 predefined
pages, on top of which you can declare your own, should that be necessary.
These are:


The VGA page

The vga page is the only page of the four that is visible to the user.  This
page holds the contents of the visible screen, and any change to that page
will be immediately visible.


The Hidden page

The hidden page is where virtually all work takes place.  To avoid all
complications relating to updating the vga page in real time, the frame is
first prepared in the hidden page and, once it is complete, is copied onto
the vga page, thus becoming visible.


The Background page

The background page holds, rather unsurprisingly, the background image.  At
the beginning of each frame the background page is copied onto the hidden
page to erase everything that was previously there and start fresh for the
new frame.


The Tiles page

The tiles page is not used for drawing, but is rather an area of memory that
tiles are stored in.  It can hold up to 255 16x16 tiles.  Note that this
page is not automatically allocated, as it is not needed if there is no
scrolling background.  UVE32 will automatically allocate this page once
ia_setscrolling (which enables a scrolling background) is called.

Related functions:
procedure ia_copypage (source,dest:word);
procedure ia_putpixel (where,x,y:word;c:byte);
function ia_getpixel (where,x,y:word):byte;
procedure ia_hline (where:word;x,y,len:integer;c:byte);
procedure ia_vline (where:word;x,y,len:integer;c:byte);
procedure ia_line(where:word; x1,y1,x2,y2:integer;color:byte);
procedure ia_box (where:word;x1,y1,x2,y2:integer;c:byte;filled:boolean);
procedure ia_box_clip
(where:word;x1,y1,x2,y2:integer;c:byte;filled:boolean);
procedure ia_cls (where:word;col:byte);
procedure ia_fadein (where,time:word);
procedure ia_newpage (var p:pagepointer; var where:word);



Sprites

A sprite is, simply put, an animated graphic object on the screen.  An
example to illustrate: in PAC-MAN, both the thing the player controls
(moves) around the maze (that yellow circle with the big mouth; I suppose
it's called the "pac-man") and the ghosts are sprites, in the sense that
they are movable entities separate from something static like the
background.

Now, I must confess that if this is the first time you hear about sprites,
you are probably totally confused by my explanation; and anyone short of a
nuclear scientist would be.  The best solution is to run some of the
examples included with UVE32 to get an intuitive idea about what sprites
are.  For the rest of this discussion, I will assume that you understand the
word sprite has nothing to do with fairies or pixies in this context.
(Although, just to confuse you more, it is possible to have a sprite that
looks like a fairy.  On second thought, forget I just said that.)

A sprite is an object that has coordinates (so it can move around) along
with some other attributes, the most important of which is what it looks
like; that is, what it's physical representation on the screen is.  A sword,
a dragon, a monster, all these are different sprites in the sense that what
you see on the screen can be uniquely identified by its appearance.  Often
the term sprite is used to refer to the picture that is visible on the
screen, but that's not what I am going to follow, because beginners will get
completely lost.

To recap:  A sprite is an object that has coordinates along with other
attributes, and which is linked to its image, its likeness, its semblance,
which is a picture that is used to represent that sprite on the screen.
That picture is not necessarily unique.  For example, ten swords displayed
on the screen are ten different sprites, in the sense that each one is
individually controllable.  However, they are all linked to the same image.
They are ten different objects with a common appearance on the screen.

I will use the term "sprite" when referring to an object and the term
"image" when I am referring to the picture that represents the sprite.

The reason the sprite is different from its image is memory constraints.
Imagine 100 identical swords displayed on the screen.  Clearly, to store the
same image 100 times along with each sprite would be clearly a waste of
memory space.  We therefore separate the image from the sprite, and from
within the sprite structure, we select one of the available images to
represent it.


Loading sprite images

Okay.  Before an image can be used, it must first be loaded into memory.  In
UVE32, there are 500 slots (positions) for images to be placed in, from 1 to
500 (0 has a special meaning, as we will soon see).  Each slot can be
thought of as a pigeon-hole that can hold a single image.  Let's say there's
a file called "pacman.uvs" that contains an image  and you want to load it
into slot 7.  You don't need to worry about memory allocation and the like,
you just say

     ia_loadspr ('pacman.uvs',7);

Note that, although the function name is ia_loadspr, it doesn't load a
sprite (sprites cannot be "loaded" in the normal sense); it loads an image.
At this point it might be a good idea to refer to the examples to see how
images are loaded.

A slight digression:  .UVS files hold a single sprite image, whereas .UVL
files hold multiple images that are loaded into consecutive locations.
UVE32 automatically detects whether a given file holds a single or multiple
images, so you don't need to stick to the extensions (but it's better if you
do, because some UVE32 utilities assume default extensions).

It is important to realize that loading an image into memory does not
display it on the screen in any way. This is so important it bears
repeating.  Loading an image does not cause anything to be displayed on the
screen.  You are simply loading an image and putting it into one of the 500
available slots.  The number of the image's slot is the image's id; the way
in which it will be referred to when you want to use it.  Continuing the
example above, every time you want to use the image 'pacman.uvs', you will
refer to it by using the number 7, the number of it's slot.

As a sidenote, UVE32 sprites are use a proprietary RLE & zero-byte variant
compression method for fast rendering.  This offers great performance but
screen-space clipping is hell.  I definitely wouldn't recommend it to the
faint-hearted :-)

Related functions:
procedure ia_loadspr (filename:string; n:integer);


Displaying a sprite

Now that the image has been loaded, we need to define a sprite and link it
to that image.  Up to 500 sprites can be simultaneously defined (ranging
from 1 to 500).  As mentioned earlier, defining a sprite is as simple as
linking it to an image, so it possesses an external, physical representation
and therefore is able to be displayed.  This is easily done, if we remember
that each image has it's own unique slot number.

A sprite is defined by linking it to an image.  As soon as a sprite is
linked to an image, it is displayed (not instantly, though; you have to wait
until a frame occurs).  Sprites are held in an array of 500 elements, with
each item being a single sprite.  This array is called spr.  So, if we want
to access the 10th sprite we would do something along the lines of

     with spr[10] do
     begin
          ...
     end;

So, how do we link the image with the sprite?  Couldn't be easier.  No,
really.  Simply set the n field of the sprite in question to the number of
the image slot.  So, from above, if the pacman is loaded into slot 7:

     with spr[10] do
     begin
          n:=7;
     end;

or simply:

     spr[10].n:=7;

Done!  Now, in the next frame, the sprite will appear at (0,0) screen
coordinates.  Of course, in a real application, some of the other fields
should be set accordingly.  A sprite is disabled (not displayed) by setting
the n field to zero.  In fact, this is the default value for all sprites
after calling ia_inituve.

A word of caution, however.  If you link a sprite to an image that has not
been loaded, the results will be unpredictable (okay, okay, it will most
likely crash the program).  So always, always make sure that the image the
sprite is linked to is loaded.  This might seem an easy thing to do, but it
gets a bit more complicated when you are dealing with more sophisticated
features such as chained sprites.  And with that, on to chained sprites.

Related functions:
procedure ia_displaysprite (n:integer;destofs,destseg:word);
procedure ia_displaysprite_mapped (n:integer;destofs,destseg:word;m:byte);
procedure ia_displaysprite_transparent
(n:integer;destofs,destseg:word;m:byte);


Sprite Chaining

In a real application, sprites rarely have a constant image throughout the
program.  Most likely, you will want the hero you are controlling to move
his legs when he is walking instead of sliding on the ground.  What this
means is that you will need to change the image that is linked to the
sprite.  This is easily done by setting n to a new number.  When dealing
with many sprites, however, this can become extremely difficult to keep
track of.  On top of that, some sprites loop through some predefined frames
of animation.  A fire, for example, can loop through five different images
to give the appearance of burning.  Can UVE32 help when it comes to this
kind of bookkeeping?  You bet.

Images are kept in an array called ln (the full description of the array
field is given at the end).  When you are loading a sprite in a slot, you
are simply giving the array index of that slot.  Each array item holds
pointers to the image data and collision detection information (stuff you
don't need to know about) along with the image's width, height (which are
handy to know about) and next field (which you do need to know about).  The
next field is the number of another image slot.  Each frame, every sprite
that is linked to an image slot will be linked to the image slot specified
in the next field.  Take a moment to re-read the above sentence.  An example
will make things clear (hopefully):

Assume that image slot number 7 has a next field with a value of 220.  This
means that any sprite which is linked to image slot 7 (i.e. spr[...].n:=7),
after a frame occurs, will be linked to image slot 220 (i.e.
spr[...].n:=220).  After yet another frame, sprites linked to image slot 220
will be linked to the number of that slot's next field.  By default, a
slot's next field is initialized to the same slot number (i.e.
ln[x].next:=x).  This means that the sprite doesn't change it's image over
time.  You can change that, however.

The "chain" can be completely arbitrary, but what's usually chained are
images with consecutive slot numbers.  This is so because the ia_loadsprite
function is capable of loading multi-image files into consecutive slots.
Anyway, even if images are loaded one by one in consecutive locations, they
can easily be chained using:

     ia_chainsprite (start slot, chain length, end slot);
     
The start slot is the first slot in the chain.  The chain length is the
number of slots in the chain.  The end slot is what the next field of the
final chain slot will be set to.  To create an infinite loop, set end
slot=start slot.  To create a disappearing sprite, set end slot=0.  In my
games, I have frequently used missile smoke sprites.  These consist of a few
chained frames of a puff of smoke (decreasing in size), with the final slot
pointing to 0.  So, I can simply define a smoke sprite and let it take its
course, without worrying about when I should delete it.  It will simply be
deleted by itself when the time comes.  (Another, more general, way is to
set the life field of the spr array, as will be explained further down the
road.)

If you have created a chain, you can pick it up at any point.  For example,
if you have ten fires that you don't want to burn in sync with one another,
you can set their starting slots at different values within the chain.
Check the examples for some, well, examples of this.

Related functions:
procedure ia_chainsprite (nr,len,endloop:integer);
procedure ia_unchainsprite (nr,len:integer);


Moving sprites

Sprites have coordinates, as specified by the x and y fields of spr.
Sprites move by changing these coordinates.  The coordinates are virtual
coordinates, in the integer range -32K to 32K in pixels.  If a sprite lies
outside the displayable area, it will not be displayed.  If it is partially
visible, it will be clipped.  Note that sprite visibility is not a
prerequisite for sprite collision.  Sprites can collide even outside the
visible area.

You can pan around the virtual world (i.e. change the visible area) by
setting vpx (viewport x) and vpy (viewport y) to appropriate values.  If you
have selected a scrolling background, it will scroll appropriately.  The
viewport always spans (vpx,vpy)-(vpx+319,vpy+199).  (vpx,vpy) always maps to
the top left of the screen, even if an animation window has been defined.

Related functions:
function ia_visiblex(i:integer):boolean;
function ia_visibley(i:integer):boolean;
function ia_visible(i:integer):boolean;
procedure ia_center(i,x,y:integer;pos:byte);


Sprite collision

Perhaps one of the most important aspects of sprites is the ability to
detect if two of them overlap ("collide").  After all, you wouldn't want
your missiles to whiz right through the enemy ships, would you?  In UVE32,
sprite collision is pixel-precise (with a few exceptions).  Bounding boxes
are not used, as they are very infuriating when dealing with 2D graphics
("But that missile didn't touch me!  I'm telling you it didn't touch me!").
You are free to use the width and height variables to implement such an
algorithm, however.

To speed up collision detection, sprites are assumed to be vertically and
horizontally monotone, i.e. a vertical or horizontal line through the sprite
intersects its edges only twice.  Think of it as the sprite being convex,
only it includes and some cases of non-convex sprites.  Holes are out of the
question.  Another way of putting it is assuming that every pixel between
the leftmost and rightmost non-black pixels in each line (and similarly
topmost and bottommost for vertical lines) is considered to be part of the
sprite, and therefore can collide with another sprite.  This requires extra
collision data to be stored along with the image data.  UVE32 takes care of
that for you automatically.  All you need to remember is to tick the "save
collision data" box when saving sprites through the utilities provided.

Sprite collision between two sprites can be detected by calling ia_collide,
which will return true if the two sprite indices provided as parameters
overlap.  Caution!  You must make sure that both sprites have collision data
embedded in them.  UVE32 does not check for that, and will use garbage data
for collision, if none is available.

A couple of notes on sprite collision.  Sprites can collide in the 64Kx64K
virtual world, even outside the screen area.  A sprite cannot collide with
itself.  Inactive sprites cannot collide (sprites for which n:=0).  Another
thing is that when there is obvious biasing towards sprite size in collision
pairs (as in the case of missile-spaceship, where the missile is usually
smaller than the ship), you will speed up collision check if you pass the
smallest sprite as the first parameter.

Related functions:
function ia_collide(a,b:integer):boolean;


Deleting sprites & images

Images can be deleted but, in my experience, it's rarely necessary.  Should
the need arise, you can call ia_delspr to delete an image.  If you load an
image on top of a filled slot, the old image will be deleted and memory will
be freed before the new one is loaded.

Sprites are a different matter altogether.  They cannot be deleted in the
normal sense.  They are "deleted" by setting the n field to zero.  Another
way is to set the next field of some image slot to zero, as described in the
section about sprite chaining.  Yet another way is to use the life field,
which simply holds the number of frames left for which the sprite will be
visible.  Once this counter counts down to zero, the sprite is deleted
(i.e., not displayed).  When a sprite is not displayed, other sprite fields
remain unchanged, so if you want a sprite to blink, you can toggle the n
field between zero and some non-zero value.

Related functions:
procedure ia_delspr (n:integer);


Other sprite attributes

For completeness, here is the whole sprite structure:

type  scb      =record
       x,y,                        sprite coords
       n,                     sprite loadnumber
       life              :integer; frames left, if 0  n:=0
       transparent  :boolean;      use sprite/background data
       map               :byte;         which palette mapping to use
       end;

Transparent specifies whether to use actual sprite data or the underlying
background data.  Why is that useful?  If map is zero, specifying that no
palette map will be used, then displaying the sprite will use the background
colors, in effect making it invisible.  That's of limited use (although I've
used it in a game).  If map is non-zero, however, background colors will be
mapped.  If the palette mapping used is, say, one where each color maps to
another of 70% brightness, then the net effect will be a sprite that looks
like a shadow.  Check the examples and the palette maps section for more
info.

And similarly, for the sprite images:

     loaded         =record
       data              :pointer;      pointer to sprite data
       collength,                  length of collision data
       length,                size in memory
       width,height :word;       size of sprite
       next              :word;         sprite sequence
       end;
     loadedarray         =array[0..nspr] of loaded;

Related Functions:
procedure ia_setspritesused (i:integer);
procedure ia_setclipdepth (i:integer);
procedure ia_setwindow (x1,y1,x2,y2:integer);



Palettes

A palette is simply a set of 256 colors, each of which is comprised of red,
green, and blue values in the range 0-63.

     palcolor       =record
       red,green,blue:byte
       end;
     palette        =array[0..255] of palcolor;

You can define your own palettes, but UVE32 has two predefined palettes
called blackpal and pcxpal.  Blackpal is simply a palette where all the
colors have RGB triplets of (0,0,0) (i.e. they are all black).  Very handy
for those fade-ins/fade-outs.  Pcxpal is where the last loaded .PCX's
palette is stored.  Loading a .PCX file does not automatically set the
palette.

Finally, a note on setting the palette.  Continuously setting the palette
DAC (as happens in fade-ins/outs) can cause "snow" to appear on the screen.
The effect can range from minimal to a complete snowstorm.  There is no way
around this, except inserting a delay between palette sets and/or
synchronizing to the VGA vertical retrace signal.  UVE32 protects against
these effects by synchronizing with the vertical retrace signal.  As all
clones are not created equal, however, this does not guarantee that it will
work on your system.  If you experience snow, stay in until the sun comes
out :-)

Related functions:
procedure ia_setpalette (pal:palette);
procedure ia_getpalette(var pal:palette);
procedure ia_loadpalette (filename:string; var p:palette);
procedure ia_fadeto (s,t:palette; steps:word);
procedure ia_weirdfadeto (s,t:palette;d:integer);



Palette maps

Palette maps are color look-up tables (CLUTs) that map each of the 256
colors to another color index.  They do not define new color values.  UVE32
defines maparray which holds 5 palette maps.

     maparray       :array[1..5] of maptab;

These maps can be applied to sprites by setting the map field of the spr
structure to the color map index (1-5) of the palette map to use.  In such a
case, the sprite is not displayed in its normal colors, but goes through a
look-up stage.  Example time:  imagine that maparray[1] has all its entries
set to 255:

     for i:=0 to 255 do maparray[1][i]:=255;

Then, if the map field of a sprite is set to 1, then every pixel of the
sprite will be displayed as color 255.  Again, the best way to understand
how these things work is to take a look at the examples.

Apart from defining a maparray entry manually, you can use ia_makeshadowmap
and ia_makeglenzmap, which set a map automatically.

Related functions:
function ia_findclosestcolor (var p:palette; r,g,b:integer):byte;
procedure ia_makeshadowmap (var p:palette; percent:integer;var
mapped:maptab);
procedure ia_makeglenzmap (var p:palette; xr,xg,xb:integer;var
mapped:maptab);



Tiles

The background page holds a static image.  You can have a larger image that
you can pan around, however.  The memory required to store such an image is
prohibitive, so the image is composed of smaller 16x16 pixel images called
tiles. You can have as many as 255 tiles that make up an image up to 5020
(stupid number, but don't ask) tiles in size (width x height). Think of
tiled floors or sidewalks and how a single tile can be repeated to fill a
larger area, only here you have a choice of 255 tiles to place at each
position.

In order to set up the scrolling background, you must first call
ia_setscrolling.  This allocates memory for the tiles.  Your tile area can
have any dimension, as long as the total tiles do not exceed 5020.  You set
your desired tile area with ia_setscrollarea.  Note that the width and
height parameters are given in tiles, not pixels.

You can scroll around the tiled imaged by changing the vpx and vpy
variables, which define the coordinates of the top-left of the screen into
your virtual world.

Tiles cannot have transparent areas.  If part of a tile is drawn in black,
then a black pixel will be placed on the screen.  The static background will
not show through.

If you pan out of the defined tile area, the screen is filled with the tile
at index 0.  In other words, the area outside of the tile area is assumed to
be filled with tile 0.

If your animation window is smaller than the screen, then the outside will
show the static background image.  If you intend to use the whole screen,
however, you can speed things up by not using the static background, since
no part of the background will be visible.  You can disable the static
background with the usebackground variable.

If you intend to use tiled backgrounds along with windowed animation, read
the bugs section for an important limitation.

Related functions:
procedure ia_loadtil (filename:string; n:integer);
procedure ia_displaytile (n:byte; lineofs,destseg:word);
procedure ia_setscrolling;
procedure ia_setscrollarea(x1,y1,w,h:integer);
procedure ia_puttile(x,y:integer;n:byte);
function ia_gettile(x,y:integer):byte;
procedure ia_setstatic;



PCXs

UVE32 is capable of loading Zsoft's popular PCX file format pictures.  The
header is ignored, however, so PCX files must be exactly 320x200 in size,
with 256 colors.  Loading a PCX does not set its palette.  The palette is
automatically saved in the pcxpal variable.

Related functions:
procedure ia_loadpcx (where:word;filename:string;seethru:byte);




Fonts

UVE32 uses BIOS mode 0x13, so there should be no problem displaying text by
calling standard procedures such as writeln.  Personally, I've never, ever
used the BIOS to print text.  Printing text in this way uses the built-in
(i.e., ugly) font.  On top of that, the background is destroyed. Have no
fear, though, because UVE32 is here to get you out of another mess.  With
its 15 fonts, horizontal and vertical printing, background preservation,
shadows, textures, proportional and fixed spacing, it's everything the font-
conscious user might want (okay, maybe not).

First thing's first, though.  In order to use fonts, some steps must be
taken.
    The file UVE.UVW must be in the current directory.
    You must load the font into memory by ia_loadfont.  All of the 15 fonts
  can be present in memory at the same time.
    You must call ia_setfontattr to set the desired font attributes.
    Finally, you can print text by calling ia_printstr.

The 15 built-in fonts must be referred to by index number.  Okay, so an
enumeration would be a better idea, but no-one is stopping you from creating
one!  The fonts are:

Font index   Font name    Font origin
0            Default 5x5  InterAction
1            Default 5x5  InterAction
             square
2            3x5          InterAction
3            3x5 square   InterAction
4            Future       Unknown
5            Antique      Unknown
6            Big          Unknown
7            Computer     Unknown
8            Deco         Unknown
9            Dott         Unknown
10           Medieval     Unknown
11           Modern       Unknown
12           Scrawl       Unknown
13           WC2          InterAction
14           5x5 Thick    InterAction

Take note of a few things when dealing with fonts.  First, make sure you
load the font before using it, otherwise you get a cryptic error message
about dereferencing a null pointer.  Second,  in the interest of speed, no
clipping is performed.  Third, the fire texture makes use of the palette
colors 224-245, so make sure you place your desired colors there (for
example, a red-yellow-white gradient). Fourth, whatever you do, never, EVER
try to .... oops, slipped my mind :-).

Related Functions:
procedure ia_setfontattr (a:byte; b:fonttextures; c:fontcpi; d:fontorient;
e:byte; f:boolean; g:byte);
function ia_strlength (s:string):word;
procedure ia_printstr (where:word;xx,yy:integer; s:string; clr:byte);
procedure ia_loadfont (i:byte);



FLIs

UVE32 is capable of loading and playing Autodesk .FLI files.  Before you
play any .FLI file you must make a call to ia_setfliparameters to set some
parameters such as looping and play rate.   Apart from that, playing .FLI
files is as easy as calling ia_playfli.  You can have more control over the
way a .FLI file is played by reverting to a lower-level interface.  Check
the functions & procedures section for more info.

Related functions:
procedure ia_openfli(filename:string);
procedure ia_playframe;
procedure ia_wait4nextframe;
procedure ia_closefli;
procedure ia_setfliparameters(a:integer;b:word;c:boolean);
procedure ia_playfli(s:string);



WAD files

It is possible to combine all the read-only files (i.e., not files such as
config and highscore files, which are written to) that your application
needs in a single master wad file.  UVEDEMO uses such a file (UVEDEMO.UVW).
UVW files are not fully supported in the shareware version.  All the
relevant code is there, but you need to register to be able to create them.

Related functions:
procedure ia_setwadfile (s:string);
function ia_searchinwad (var fp:file;lookingfor:string):longint;




UVE Interface


Unit interface section

const     nspr      =500;               maximum number of sprites
     maxtiles  =5020;              maximum number of scrolling area in tiles

type   scb          =record
       x,y,                        sprite coords
       n,                     sprite loadnumber
       life              :integer; frames left, if 0  n:=0
       transparent  :boolean;      use sprite/background data
       map               :byte;         which palette mapping to use
       end;
     scbarray  =array[0..nspr] of scb;
     loaded         =record
       data              :pointer; pointer to sprite data
       collength,                  length of collision data
       length,                size in memory
       width,height :word;       size of sprite
       next              :word;         sprite sequence
       end;
     loadedarray         =array[0..nspr] of loaded;
     maptab              =array[0..255] of byte; used for colormapping
     fontorient          =(horizontal,vertical); font attribute types
     fontcpi        =(fixed,proportional);
     fonttextures        =(plain,fire);
     pagetype       =array[0..$FFFE] of byte;
     pagepointer         =^pagetype;
     palcolor       =record
       red,green,blue:byte
       end;
     palette        =array[0..255] of palcolor;

var  vpx,vpy        :integer;      viewport topleft corner coords
     hidden              :word;              segment of the hidden page
     hiddenpoint         :pagepointer;  pointer to hidden page
     background          :word;         segment of background
     backgroundpoint     :pagepointer;       pointer to background
     tiles               :word;              segment of tiles
     tilespoint          :pagepointer;  pointer to tiles
     pcxpal              :palette;      last PCXs palette
     blackpal       :palette;      all blacks (0,0,0)
     spritesloaded  :integer;      set by last "loadSPR" call
     retraceenable,                wait 4 vertical retrace?
     usebackground  :boolean;      copy bg to hidden page?
     developermode  :boolean;      show developer stats
     maparray       :array[1..5] of maptab;
                                   these tables are uses to map
                                   colors when display method
                                   is eg shadow, glenz, ...
     spr            :scbarray;
     ln             :loadedarray;
     vga            :word;

     lastframe      :boolean;
     textenable          :boolean;      enables uve_text
     fliframenumber :word;              number of current FLI frame
     frame               :integer;      current uve frame number



Other variables

    spritesloaded:  Sprites loaded by last ia_loadspr call

    retraceenable (false):  If true, UVE waits for a vertical retrace
 signal before copying the hidden page to the vga page.  This is not needed,
 but included for the sake of completeness.  In the unlikely case you are
 experiencing screen flicker, turn this option on.  Minimizes flickering, but
 slows down frame rate.

    usebackground (true):   If true, UVE will copy the background page to
 the hidden page before anything else to clear the last frame.   If you've
 got a full-screen scrolling background, however, this is not necessary.
 Turning this option off will improve frame rate.

    developermode (false):  When true, displays a bar on the top-left of
 the screen with some statistics.  Each pixel in the graph corresponds to 1
 millisecond:
         White portion represents time spend by UVE rendering the screen.
         Blue portion represents time taken by your program apart from rendering
      time.  This includes game logic time, collision checks, keyboard input etc.
    Red portion represents time taken to copy hidden to vga page.  The
reason this is separate is that, depending on your VGA, it can take up to
90% of the total frame time.
         White arrow under bar represents desired (set) frame rate.
 Note that colors mentioned correspond to default palette.

    lastframe (false):  True if current FLI frame is the last frame.  Used
 for manual FLI play loops.
    textenable (true):  Set to false if you don't want any text output from
UVE (for example when loading sprites).  Output is always disabled when in
graphics mode.
    fliframenumber (0):  Current FLI frame number
    frame (0):  Current UVE frame number



Functions & Procedures

The functions and procedures of UVE are divided into four categories:
general-purpose, beginner, intermediate and advanced.  General purpose
procedures are simple "utility" procedures.  Beginner entries include all
procedures that you must absolutely know about in order to use UVE.
Intermediate entries refer to commands that you will use frequently when
you've learned the ropes.  Advanced entries, finally, provide a lower lever
interface to UVE and, as such, are more powerful and allow for extensive
customization.  You do not have to know any of the advanced commands, but
they do come in handy in certain situations.


General Purpose Commands

function i2s (i:integer):string;
Purpose        Convert an integer to its string representation
Parameters     i    Integer variable to be converted
Return         String representation of i
Notes          -
See also       l2s, w2s


function w2s (w:word):string;
Purpose        Convert a word to its string representation
Parameters     w    Word variable to be converted
Return         String representation of w
Notes          i2s, l2s
See also       -


function l2s (l:longint):string;
Purpose        Convert an long integer to its string representation
Parameters     l    Longint variable to be converted
Return         String representation of l
Notes          -
See also       i2s, w2s


function max (a,b:integer):integer;
Purpose        Return greater of two numbers
Parameters     a,b  Integers to be compared
Return         Greatest integer
Notes          -
See also       min


function min (a,b:integer):integer;
Purpose        Return smaller of two numbers
Parameters     a,b  Integers to be compared
Return         Smallest integer
Notes          -
See also       max


procedure ia_checkfile (s:string);
Purpose        Check whether a file exists
Parameters     s    Filename
Return         -
Notes          Calls ia_error if file does not exist
See also       -


procedure ia_checkmem (w:word);
Purpose        Check for available memory
Parameters     w    Requested memory in bytes
Return         -
Notes          Calls ia_error if free memory is less than w
See also       -



Beginner Commands

procedure ia_loadtil (filename:string; n:integer);
Purpose        Load a tile
Parameters     filename  UVT or UVL file name
          n    Index of tile
Return         -
Notes          Calls ia_error if file is not found
See also       ia_setscrolling, ia_puttile, ia_gettile, ia_displaytile


procedure ia_loadspr (filename:string; n:integer);
Purpose        Load a sprite
Parameters     filename  UVS or UVL file name
          n    Index of sprite
Return         -
Notes          Calls ia_error if file is not found
          Sets spritesloaded to the number of sprites loaded
See also       ia_delspr


procedure ia_loadpcx (where:word; filename:string; seethru:byte);
Purpose        Load a PCX file
Parameters     where     Page segment
          filename  PCX file name
          seethru   Transparent color (255=none)
Return         -
Notes          PCX palette is stored in pcxpal
See also       -


procedure ia_setpalette (pal:palette);
Purpose        Set the current palette
Parameters     pal  Palette to set
Return         -
Notes          -
See also       ia_loadpalette, ia_getpalette


procedure ia_loadpalette (filename:string; var p:palette);
Purpose        Load a palette
Parameters     filename  PAL file name
          p    Palette variable to store result into
Return         -
Notes          -
See also       ia_setpalette, ia_getpalette


procedure ia_setscrolling;
Purpose        Set scrolling (tiled) background
Parameters     -
Return         -
Notes          Allocates tiles page first time it's called
See also       ia_setstatic


procedure ia_setscrollarea (x1,y1,w,h:integer);
Purpose        Set scrolling area
Parameters     x1,y1     Coordinates of top-left corner in pixels
          w,h  Width and height of scroll area in tiles
Return         -
Notes          x1,y1 are automatically aligned on a 16x16 grid
See also       ia_setscrolling


procedure ia_puttile (x,y:integer; n:byte);
Purpose        Set a tile on the scroll area
Parameters     x,y  Coordinates to place tile in pixels
          n    Tile number
Return         -
Notes          x1,y1 are automatically aligned on a 16x16 grid
See also       ia_gettile


procedure ia_setfontattr (a:byte; b:fonttextures; c:fontcpi; d:fontorient;
e:byte; f:boolean; g:byte);
Purpose        Set font attribute
Parameters     a    Font number
          b    Font texture.  Can be plain or fire
          c    Character spacing.  Can be fixed or proportional
          d    Font orienation.  Can be horizontal or vertical
          e    Background color.  Use 255 for transparent background
          f    True for a font shadow to be displayed
          g    Shadow color
Return         -
Notes          Fire uses color indices 224-245
          Font must be loaded first
See also       ia_loadfont, ia_strlength, ia_printstr


procedure ia_printstr (where:word; xx,yy:integer, s:string; clr:byte);
Purpose        Print a string
Parameters     where     Page segment
          xx,yy     Coordinates where string printing will start in pixels
          s    String to print
          clr  String color
Return         -
Notes          Use xx=-32768 to center the string on screen
          No clipping is performed
See also       ia_loadfont, ia_setfontattr, ia_strlength


procedure ia_loadfont (i:byte);
Purpose        Load a font
Parameters     i    Font number
Return         -
Notes          Calls ia_error if UVE.UVW is not present in the current
directory
See also       ia_setfontattr, ia_strlength, ia_printstr


procedure ia_powerup;
Purpose        Switch to graphics mode 0x13
Parameters     -
Return         -
Notes          -
See also       ia_shutdown


procedure ia_shutdown;
Purpose        Switch to text mode 0x03
Parameters     -
Return         -
Notes          -
See also       ia_powerup


procedure ia_playfli (s:string);
Purpose        Play a FLI file
Parameters     s    FLI file name
Return         -
Notes          Calls ia_error if file cannot be found
See also       ia_setfliparameters, ia_openfli, ia_playframe,
ia_wait4nextframe, ia_closefli


procedure ia_inituve;
Purpose        Initialize UVE32
Parameters     -
Return         -
Notes          Call before anything else.
          Call once only.
See also       -


procedure ia_doframe;
Purpose        Execute frame
Parameters     -
Return         -
Notes          Calls parts 1,2 and 3
See also       ia_doframepart1, ia_doframepart2, ia_doframepart3



Intermediate Commands

procedure ia_getpalette (var pal:palette);
Purpose        Get the current palette
Parameters     pal  Palette variable to store result into
Return         -
Notes          -
See also       ia_loadpalette, ia_setpalette


procedure ia_setwadfile (s:string);
Purpose        Set the current UVW file
Parameters     s    Filename
Return         -
Notes          When s is specified, all PCX/UVS/UVL/FLI/UVT files will be
loaded from s
          To load files normally, call ia_setwadfile('');
          Calls ia_error if file does not exist
See also       ia_searchinwad


procedure ia_copypage (source,dest:word);
Purpose        Copy a page
Parameters     source    Source page segment
          target    Target page segment
Return         -
Notes          -
See also       -


procedure ia_cls (where:word; col:byte);
Purpose        Clear a page
Parameters     where     Page segment
          col  Color to use
Return         -
Notes          -
See also       -


procedure ia_putpixel (where,x,y:word; c:byte);
Purpose        Plot a pixel
Parameters     where     Page segment
          x,y  Point coordinates
          c    Color to use
Return         -
Notes          No clipping is performed
See also       ia_getpixel


function ia_getpixel (where,x,y:word):byte;
Purpose        Read a pixel
Parameters     where     Page segment
          x,y  Point coordinates
Return         Color of specified pixel
Notes          No clipping is performed
See also       ia_putpixel


procedure ia_hline (where:word; x,y,len:integer; c:byte);
Purpose        Draw a horizontal line
Parameters     where     Page segment
          x,y  Starting point coordinates
          len  Line length in pixels
Return         -
Notes          Performs no clipping
See also       ia_vline, ia_line


procedure ia_vline (where:word; x,y,len:integer; c:byte);
Purpose        Draw a vertical line
Parameters     where     Page segment
          x,y  Starting point coordinates
          len  Line height in pixels
Return         -
Notes          Performs no clipping
See also       ia_hline, ia_line


procedure ia_line (where:word; x1,y1,x2,y2:integer; color:byte);
Purpose        Draw a line using Bresenham's algorithm
Parameters     where     Page segment
          x1,y1     Start point coordinates
          x2,y2     End point coordinates
          color     Color to use
Return         -
Notes          Performs no clipping
See also       ia_vline, ia_hline


procedure ia_box (where:word; x1,y1,x2,y2:integer; c:byte; filled:boolean);
Purpose        Draw a box
Parameters     where     Page segment
          x1,y1     Start point coordinates
          x2,y2     End point coordinates
          c    Color to use
          filled    If true, box is filled with color c
               If false, only a hollow rectangle is drawn
Return         -
Notes          Performs no clipping
See also       ia_box_clip


procedure ia_box_clip (where:word; x1,y1,x2,y2:integer; c:byte;
filled:boolean);
Purpose        Draw a box
Parameters     where     Page segment
          x1,y1     Start point coordinates
          x2,y2     End point coordinates
          c    Color to use
          filled    If true, box is filled with color c
               If false, only a hollow rectangle is drawn
Return         -
Notes          Same as ia_box, but performs clipping as well
See also       ia_box


procedure ia_fadein (where,time:word);
Purpose        Dissolve a page onto the VGA page
Parameters     where     Page to be dissolved
          time Speed of transition
Return         -
Notes          Very slow on some 386s
See also       -


procedure ia_makeshadowmap (var p:palette; percent:integer; var
mapped:maptab);
Purpose        Make a shadow map
Parameters     p    Palette variable to use as a base for mapping
          percent   Shadow percentage
          mapped    Map table variable to store result into
Return         -
Notes          Percent can be more than 100, which will result in a brighter
colormap
See also       ia_findclosestcolor, ia_makeglenzmap


procedure ia_makeglenzmap (var p:palette; xr,xg,xb:integer; var
mapped:maptab);
Purpose        Make a glenz (translucency) map
Parameters     p    Palette variable to use as a base for mapping
          xr,xg,xb  RGB components to add to each color
          mapped    Map table variable to store result into
Return         -
Notes          xr,xg,xb can be positive or negative
See also       ia_findclosestcolor, ia_makeshadowmap


procedure ia_fadeto (s,t:palette; steps:word);
Purpose        Cross-fade between two palettes using linear interpolation
Parameters     s    Source palette
          t    Target palette
          steps     Cross-fade duration
Return         -
Notes          -
See also       ia_weirdfadeto, ia_loadpalette, ia_setpalette, ia_getpalette


procedure ia_weirdfadeto (s,t:palette; d:integer);
Purpose        Cross-fade between two palettes using integer RGB matching
Parameters     s    Source palette
          t    Target palette
          steps     Cross-fade duration
Return         -
Notes          Faster than ia_fadeto but may result in slight hue shifts
while cross-fading
See also       ia_fadeto, ia_loadpalette, ia_setpalette, ia_getpalette


function ia_visible (i:integer):boolean;
Purpose        Test for sprite visibility in both axes
Parameters     i    Sprite number
Return         True if sprite is visible on screen
Notes          Uses bounding box, not actual sprite geometry
See also       ia_visiblex, ia_visibley


procedure ia_center (i,x,y:integer; pos:byte);
Purpose        Center a sprite around a point
Parameters     i    Sprite number
          x,y  Coordinates of center point
          pos  Centering method:
               2    (x,y) becomes mid-bottom of sprite
               4    (x,y) becomes mid-left of sprite
               5    (x,y) becomes center of sprite
               6    (x,y) becomes mid-right of sprite
               8    (x,y) becomes mid-top of sprite
Return         -
Notes          Hint for centering method: Look at the numeric keypad.
Sprite boundary is
          123/456/789 "box".  Centering method corresponds to number on each
key.
See also       -


function ia_collide (a,b:integer):boolean;
Purpose        Test for sprite collision
Parameters     a,b  Sprite numbers
Return         True if there is a collision between sprites a and b
Notes          Collision can be off-screen
          Both sprites must have collision data embedded in their format!
See also       -


procedure ia_chainsprite (nr,len,endloop:integer);
Purpose        Chain sprites together
Parameters     nr   Start sprite number for chain
          len  Length of chain
          endloop   Final chain sprite link
Return         -
Notes          Sprite will cycle nr nr+1  nr+2  ...  nr+len  endloop
          Infinite loops can be created by setting endloop=nr
See also       ia_unchainsprite


procedure ia_unchainsprite (nr,len:integer);
Purpose        Unchain previously chained sprites
Parameters     nr   Start sprite number for chain
          len  Unchain length
Return         -
Notes          -
See also       ia_chainsprite


function ia_gettile (x,y:integer):byte;
Purpose        Get a tile from the scroll area
Parameters     x,y  Coordinates to get tile from in pixels
Return         Tile number under x,y
Notes          x1,y1 are automatically aligned on a 16x16 grid
See also       ia_puttile


procedure ia_setstatic;
Purpose        Set static background (disable scrolling background)
Parameters     -
Return         -
Notes          Tiles page is not deallocated
See also       ia_setscrolling


procedure ia_setcycletime (i:integer);
Purpose        Set frame duration
Parameters     i    Frame duration in milliseconds
Return         -
Notes          Frame rate will be limited to i.
          Has no effect if frames cannot be displayed as fast as i
See also       -


procedure ia_setwindow (x1,y1,x2,y2:integer);
Purpose        Set animation window
Parameters     x1,y1     Coordinates of top-left corner of animation window
          x2,y2     Coordinates of bottom-right corner of animation window
Return         -
Notes          -
See also       -



Advanced Commands

function clock:longint;
Purpose        Return the current time
Parameters     -
Return         Milliseconds elapsed since midnight
Notes          -
See also       -


procedure ia_error (caller:string; errornum:byte; param:string);
Purpose        Error handling routine
Parameters     caller    Procedure that generated the error
          errornum Error number
          param     Parameter that caused the error
Return         -
Notes          Program halts after printing error.
          Possible error numbers are.
               1    Parameter(s) out of range.
               2    File does not exist.
               3    Not an UVE file.
               4    Wrong file type.
               5    Not enough memory.
               6    Attempt to dereference nil pointer.
               7    No VGA display adapter detected.
               8    Scrolling area too large.
               9    Tile placed out of scroll area.
See also       -


function ia_detectvga:boolean;
Purpose        Detect the presence of a VGA adapter
Parameters     -
Return         True if VGA present
Notes          -
See also       -


procedure ia_drawasciiscreen;
Purpose        Draw UVE opening text screen
Parameters     -
Return         -
Notes          -
See also       ia_uvetext


procedure ia_uvetext (caller, strng, parameter: string);
Purpose        Print out text in UVE standardized format
Parameters     caller    Calling procedure
          parameter Text to print
Return         -
Notes          -
See also       ia_drawasciiscreen


procedure ia_waitretrace;
Purpose        Wait for VGA vertical retrace signal
Parameters     -
Return         -
Notes          Not needed, but included for completeness
See also       -


procedure ia_delspr (n:integer);
Purpose        Delete a sprite from memory
Parameters     n    Sprite number to delete
Return         -
Notes          -
See also       ia_loadspr


function ia_searchinwad (var fp:file; lookingfor:string):longint;
Purpose        Position a file pointer to a specified entry in a UVW file
Parameters     fp   File handle (must be of type FILE)
Return         Size of file requested
Notes          Calls ia_error if entry is not present in UVW
See also       ia_setwadfile


function ia_findclosestcolor (var p:palette; r,g,b:integer):byte;
Purpose        Find closest color using least squares method
Parameters     p    Palette var to search in
          r,g,b     Desired RGB components
Return         Index of closest color matching RGB components specified
Notes          -
See also       ia_makeshadowmap, ia_makeglenzmap


function ia_visiblex (i:integer):boolean;
Purpose        Test for sprite visibility in x-axis
Parameters     i    Sprite number
Return         True if sprite is visible on screen x-extents
Notes          Uses bounding box, not actual sprite geometry
See also       ia_visibley, ia_visible


function ia_visibley (i:integer):boolean;
Purpose        Test for sprite visibility in y-axis
Parameters     i    Sprite number
Return         True if sprite is visible on screen y-extents
Notes          Uses bounding box, not actual sprite geometry
See also       ia_visiblex, ia_visible


procedure ia_displaysprite (n:integer; destofs,destseg:word);
Purpose        Display a sprite
Parameters     n    Sprite number
          destofs   Destination offset
          destseg   Destination segment
Return         -
Notes          Performs no clipping
See also       ia_displaysprite_mapped, ia_displaysprite_transparent


procedure ia_displaysprite_mapped (n:integer; destofs,destseg:word; m:byte);
Purpose        Display a sprite using a map table
Parameters     n    Sprite number
          destofs   Destination offset
          destseg   Destination segment
          m    Map table index
Return         -
Notes          Performs no clipping
See also       ia_displaysprite, ia_displaysprite_transparent


procedure ia_displaysprite_transparent (n:integer; destofs,destseg:word;
m:byte);
Purpose        Display a transparent sprite using a map table
Parameters     n    Sprite number
          destofs   Destination offset
          destseg   Destination segment
          m    Map table index
Return         -
Notes          Performs no clipping
See also       ia_displaysprite, ia_displaysprite_mapped


procedure ia_displaytile (n:byte; lineofs,destseg:word);
Purpose        Display a tile
Parameters     n    Tile number
          lineofs   Destination offset
          destseg   Destination segment
Return         -
Notes          Performs no clipping
See also       ia_loadtil, ia_gettile, ia_puttile


procedure ia_doframepart1;
Purpose        Execute first part of frame cycle
Parameters     -
Return         -
Notes          Copies background page onto hidden page and/or constructs
tiled background
See also       ia_doframepart2, ia_doframepart3, ia_doframe


procedure ia_doframepart2;
Purpose        Execute second part of frame cycle
Parameters     -
Return         -
Notes          Display all sprites onto hidden page
See also       ia_doframepart1, ia_doframepart3, ia_doframe


procedure ia_doframepart3;
Purpose        Execute third part of frame cycle
Parameters     -
Return         -
Notes          Copy  hidden page to vga page
See also       ia_doframepart1, ia_doframepart2, ia_doframe


procedure ia_setspritesused (i:integer);
Purpose        Set number of active sprites
Parameters     i    Sprite number
Return         -
Notes          Only sprites with number between 1 and i will be displayed
See also       -


procedure ia_setclipdepth (i:integer);
Purpose        Set number of sprites clipped to screen ("in front" of
     animation window)
Parameters     i    Sprite number
Return         -
Notes          Sprites with number between 1 and i will be clipped to
320x200 screen
          Sprites with number between i+1 and nmax will be clipped to
animation window
See also       -


function ia_strlength (s:string):word;
Purpose        Get string length
Parameters     s    String to calculate length of
Return         Length of string in pixels when printed out in the current
font attributes
Notes          -
See also       ia_loadfont, ia_setfontattr, ia_printstr


procedure ia_newpage (var p:pagepointer; var where:word);
Purpose        Allocate a new page
Parameters     -
Return         p    points to the new allocated page
          where     holds new page segment
Notes          Calls ia_error if there is not enough memory left
See also       -


procedure ia_openfli (filename:string);
Purpose        Open a FLI file
Parameters     filename  FLI file name
Return         -
Notes          Calls ia_error if file is cannot be found
See also       ia_setfliparameters, ia_playframe, ia_wait4nextframe,
ia_closefli, ia_playfli


procedure ia_playframe;
Purpose        Play the next frame of a FLI file
Parameters     -
Return         -
Notes          -
See also       ia_setfliparameters, ia_openfli, ia_wait4nextframe,
ia_closefli, ia_playfli


procedure ia_wait4nextframe;
Purpose        Wait until current FLI frame time expires
Parameters     -
Return         -
Notes          -
See also       ia_setfliparameters, ia_openfli, ia_playframe, ia_closefli,
ia_playfli


procedure ia_closefli;
Purpose        Close a FLI file
Parameters     -
Return         -
Notes          -
See also       ia_setfliparameters, ia_openfli, ia_playframe,
ia_wait4nextframe, ia_playfli


procedure ia_setfliparameters (a:integer; b:word; c:boolean);
Purpose        Set FLI play parameters
Parameters     a    FLI playing speed
          b    FLI loop times
          c    True if FLI can be interrupted by a keypress
Return         -
Notes          Use a=-1 to use FLI internal speed
See also       ia_openfli, ia_playframe, ia_wait4nextframe, ia_closefli,
ia_playfli




Supporting Utilities

UVSINFO

UVSINFO is a simple utility that gives information about sprites contained
in a single/multiple sprite file (.UVS/.UVL).



PCX2UVS

PCX2UVS is a utility that converts a PCX file into a sprite (.UVS) file.  It
can also optionally save the PCX's palette for use with that sprite.  The
PCX's background must be black (color index 0).  UVE32 automatically
calculates the bounding box from the PCX image and saves the sprite.  Any
part of the sprite that is drawn in black will be completely transparent
when displayed on the screen.  A PCX file can only hold a single sprite.
(You can get a far more powerful version of PCX2UVS if you register).



PCX2UVT

PCX2UVT is a utility that converts a PCX file into a tile (.UVT) file.  The
PCX's background must be black (color index 0).  No bounding box is used.
The first non-black pixel found is assumed to be the top-left pixel of a
16x16 tile.  You can have multiple tiles in the PCX.  In such a case, the
tiles will all be saved in a single file in the order they were detected
(top-to-bottom, left-to-right).

Note:  As no bounding box is used when saving tiles, the top-left pixel of
each tile must not be black, so that the start of a tile is properly
detected.



LIBMAKER

LIBMAKER is a powerful utility that allows you to combine multiple files
together.  Its most obvious use is to concatenate .UVS or .UVT files into
library (.UVL) files.  It cannot be used to create wad files (.UVW).  The
files will be concatenated in the order they were selected.

There is a maximum of 100 files that can be simultaneously displayed.  This
means that your UVL files can contain at most 100 sprites/tiles.
Workaround:  First split your files into groups of (at most) 100 files,
combine them separately, and then combine the resultant UVL files into your
final master UVL file.  Hope you got that.




Known bugs... err.. features

The following list contains all the bugs/limitations I am aware of (but
don't intend to fix, at least in the near future).

    When using a scrolling (tiled) background, the animation window must be
  at least 16 pixels long in both dimensions, i.e. it must be able to contain
  at least one full tile.  Tiles are not clipped properly if the animation
  window is smaller than that.




UVE32 Frequently Asked Questions

    Why is there only one question in the UVE32 FAQ?
     Because this is the first public release of UVE32, and I haven't
     received any questions yet.  Doh!




Where can I get UVE32?

The two primary sites where the lastest version of UVE32 will be uploaded
first are:

    The SimTel archive in the US (ftp to ftp.simtel.net or ftp.cdrom.com)
  in pub/simtelnet/msdos/turbopas/
    The X2 archive in Finland (ftp to x2ftp.oulu.fi) in
  pub/msdos/programming/libs/

Of course, since everybody mirrors everybody else these days, it should soon
spread to just about everywhere.  If you cannot access these sites, try
getting UVE32 from a nearby mirror site.  At the time of this writing, the
official mirroring sites are:

For the SimTel archive:

Country             Host                          Directory
Argentina           ftp.satlink.com               /pub/mirrors/simtelnet
Australia           ftp.bhp.com.au                /pub/simtelnet
Australia           ftp.iniaccess.net.au          /pub/simtelnet
Australia           ftp.tas.gov.au                /pub/simtelnet
Australia           sunsite.anu.edu.au            /pub/pc/simtelnet
Austria             ftp.univie.ac.at              /mirror/simtelnet
Belgium             ftp.linkline.be               /mirror/simtelnet
Belgium             ftp.tornado.be                /pub/simtelnet
Bulgaria            ftp.eunet.bg                  /pub/simtelnet
Brazil              ftp.iis.com.br                /pub/simtelnet
Brazil              ftp.unicamp.br                /pub/simtelnet
Canada,Ottawa       ftp.crc.doc.ca                /systems/ibmpc/simtelnet
Canada,Vancvr       ftp.direct.ca                 /pub/simtelnet
Chile               sunsite.dcc.uchile.cl         /pub/Mirror/simtelnet
China               ftp.pku.edu.cn                /pub/simtelnet
Czech Republic      ftp.eunet.cz                  /pub/simtelnet
Czech Republic      pub.vse.cz                    /pub/simtelnet
Czech Republic      ftp.zcu.cz                    /pub/simtelnet
Finland             ftp.funet.fi                  /mirrors/ftp.simtel.net/pub/simtelnet
France              ftp.grolier.fr                /pub/simtelnet
France              ftp.ibp.fr                    /pub/simtelnet
Germany             ftp.mpi-sb.mpg.de             /pub/simtelnet
Germany             ftp.rz.ruhr-uni-bochum.de     /pub/simtelnet
Germany             ftp.tu-chemnitz.de            /pub/simtelnet
Germany             ftp.uni-heidelberg.de         /pub/simtelnet
Germany             ftp.uni-magdeburg.de          /pub/mirrors/simtelnet
Germany             ftp.uni-paderborn.de          /pub/simtelnet
Germany             ftp.uni-trier.de              /pub/pc/mirrors/simtelnet
Germany             ftp.rz.uni-wuerzburg.de       /pub/pc/simtelnet
Greece              ftp.ntua.gr                   /pub/pc/simtelnet
Hong Kong           ftp.cs.cuhk.hk                /pub/simtelnet
Hong Kong           ftp.hkstar.com                /pub/simtelnet
Hong Kong           sunsite.ust.hk                /pub/simtelnet
Israel              ftp.huji.ac.il                /pub/simtelnet
Italy               cis.utovrm.it                 /simtelnet
Italy               ftp.flashnet.it               /pub/simtelnet
Italy               ftp.unina.it                  /pub/simtelnet
Italy               mcftp.mclink.it               /pub/simtelnet
Japan               ftp.iij.ad.jp                 /pub/simtelnet
Japan               ftp.riken.go.jp               /pub/simtelnet
Japan               ftp.saitama-u.ac.jp           /pub/simtelnet
Japan               ftp.u-aizu.ac.jp              /pub/PC/simtelnet
Japan               ring.aist.go.jp               /pub/simtelnet
Japan               ring.asahi-net.or.jp          /pub/simtelnet
Latvia              ftp.lanet.lv                  /pub/mirror/simtelnet
Malaysia            ftp.jaring.my                 /pub/simtelnet
Malaysia            ftp.mimos.my                  /pub/simtelnet
Mexico              ftp.gdl.iteso.mx              /pub/simtelnet
Netherlands         ftp.euro.net                  /d5/simtelnet
Netherlands         ftp.nic.surfnet.nl            /mirror-archive/software/simtelnet
New Zealand         ftp.vuw.ac.nz                 /pub/simtelnet
Norway              ftp.bitcon.no                 /pub/simtelnet
Poland              ftp.cyf-kr.edu.pl             /pub/mirror/Simtel.Net
Poland              ftp.icm.edu.pl                /pub/simtelnet
Poland              ftp.man.poznan.pl             /pub/simtelnet
Portugal            ftp.ip.pt                     /pub/simtelnet
Portugal            ftp.ua.pt                     /pub/simtelnet
Romania             ftp.sorostm.ro                /pub/simtelnet
Singapore           ftp.nus.sg                    /pub/simtelnet
Slovakia            ftp.uakom.sk                  /pub/simtelnet
Slovenia            ftp.arnes.si                  /software/simtelnet
South Africa        ftp.is.co.za                  /pub/simtelnet
South Africa        ftp.sun.ac.za                 /pub/simtelnet
South Korea         ftp.nuri.net                  /pub/simtelnet
South Korea         ftp.sogang.ac.kr              /pub/simtelnet
South Korea         sunsite.snu.ac.kr             /pub/simtelnet
Spain               ftp.rediris.es                /mirror/simtelnet
Sweden              ftp.sunet.se                  /pub/simtelnet
Switzerland         ftp.switch.ch                 /mirror/simtelnet
Taiwan              ftp.ncu.edu.tw                /Packages/simtelnet
Taiwan              nctuccca.edu.tw               /mirror/simtelnet
Thailand            ftp.nectec.or.th              /pub/mirrors/simtelnet
UK, Edinburgh       emwac.ed.ac.uk                /mirrors/simtelnet
UK, London          ftp.demon.co.uk               /pub/simtelnet
UK, Lancaster       micros.hensa.ac.uk            /pub/simtelnet
UK, London          sunsite.doc.ic.ac.uk          /packages/simtelnet
US, California      ftp.cdrom.com                 /pub/simtelnet
US, California      ftp.digital.com               /pub/micro/pc/simtelnet
US, Illinois        uiarchive.cso.uiuc.edu        /pub/systems/pc/simtelnet
US, Mass.           ftp.bu.edu                    /pub/mirrors/simtelnet
US, Michigan        oak.oakland.edu               /pub/simtelnet
US, New York        ftp.rge.com                   /pub/systems/simtelnet
US, Oklahoma        ftp.ou.edu                    /pub/simtelnet
US, Oregon          ftp.orst.edu                  /pub/simtelnet
US, Utah            ftp.cyber-naut.com            /pub/simtelnet
US, Virginia        mirrors.aol.com               /pub/simtelnet


For the X2 archive:

     Site: ftp.ibp.fr (France)
     Path: /pub/pc/x2ftp/
     Mirror: books,msdos
     Update: 0330 GMT

     Site: ftp.rz.uni-karlsruhe.de (Germany)
     Path: /pub/programming/mirror.x2ftp/
     Mirror: books,msdos,unix
     Update: 0200 GMT

     Site: ftp.infomagic.com (USA)
     Path: /pub/mirrors/x2ftp/
     Mirror: amiga,books,console,msdos,standards
     Update: 0400 GMT

     Site: illusion.shiny.it (Italy)
     Path: /pub/x2ftp/
     Mirror: msdos
     Update: 0500 GMT

     Site: mirrors.aol.com (USA)
     Path: /pub/x2ftp
     Mirror: books,console,msdos
     Update: 2330 GMT

     Site: ftp.ee.techpta.ac.za (168.172.8.5) (South Africa)
     Path: /pub/mirrors/x2ftp/
     Mirror:
     Update: 2300 GMT

     Site: ftp.lanet.lv (Latvia)
     Path: /pub/mirror/x2ftp/
     Mirror: books,msdos
     Update: 0130 GMT

     Site: http://www2.cp.eng.chula.ac.th/mirror1/x2ftp
     Mirror: msdos
     Update: 2100 GMT
     Freq.: weekly (Friday)
     Admin: ftpadm@cpu.cp.eng.chula.ac.th




Contacting InterAction software

You can contact me for any reason, whether it's to ask for registration
information, to ask if/how you can do something in UVE32, to report a bug,
or just to say what you like/don't like about UVE32.

When writing in to report a bug or ask something about a command, please
take the time to read through the manual.  There is a good chance the answer
you are looking for is already there.  Also, check the FAQ for answers to
frequently asked questions.  When you writing in with a question, please
include in your mail information about the version of UVE32 you are using.

Okay, by far the best way to contact me is through e-mail.  My address is:

                              cbp@doc.ic.ac.uk

Note that this address is only valid until the 1st of July, 1998.
Furthermore, avoid sending mail to that address during the Christmas,
Easter, and Summer holidays as I will not be checking my mail regularly
during those times.  You can alternatively send mail to the following
address:

                                robin@hol.net

It's probably  A Good Idea to send your mail to both addresses to minimize
latency time (I love it when I use jargon).  Some e-mail bounces, so if you
haven't heard from me in 15 days, send your mail again, perhaps including
more complete or alternative reply addresses.

If you have no access to the Internet, You can use conventional surface
mail, although I can't guarantee how long it's going to take before you get
an answer.  You can write to:

                            Constantine Prouskas
                           4 Adrianoupoleos street
                              GR 156-69 Papagou
                               Athens, GREECE




Registering

UVE32 is shareware.  It is not free.  If you use UVE32 for 21 days and wish
to continue using it, you must register it.  Read the License Agreement for
more information on what you are and are not allowed to do.  By registering
you are acknowledging all he work that has gone behind this product and
supporting further development.

You can register for the equivalent of US$20.  You can pay by check, cash,
international
postal money order or direct transfer to my bank account.  Since addresses,
bank accounts and the like are subject to change, however, it's best if you
contact me at the above address first.  Apart from notifying me that you
want to register, we can work out the payment method that is most
convenient.

By registering, you get:

    My eternal gratitude :-)
    The latest version of UVE32 for Turbo Pascal 6.0 & 7.0, plus the
  protected mode version for Borland Pascal 7.0.
    Unlimited mail/e-mail support (including hot tips on how it's possible
  to have a 2-player split screen in UVE32).
    The complete documentation in Microsoft Word 6.0 (.DOC), WordPerfect
  5.x (.DOC) and Rich Text Format (.RTF) formats, complete with advanced
  formatting and tables.
    Registered versions of all the supporting utilities, including UVSINFO,
PCX2UVS, PCX2UVT, LIBMAKER.
    An advanced, powerful version of PCX2UVS that allows multiple sprites
per PCX and complete control over the save region.
    WADMAKER:  An extra utility that can create .UVW files.
    WADVIEW:  An extra utility that shows the contents of .UVW files.
    FLI2UVL:  An extra utility that directly creates a UVL file from a FLI
file.




Epilogue

This, as they say, is it.  You can take it from here.  I've supplied the
tools, you supply the inspiration.

One final request:  If you ever use UVE32 to write any sort of application
(especially what it was meant for, games), I ask that you send me a piece of
mail saying what it is and where I can get it.  It's your way of letting me
know that all the hours of hard work that have gone into UVE32 have really
paid off.

Go forth and make some magic.



