home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-11-17 | 127.7 KB | 2,759 lines |
- ░░░░░░▄ ░░░▄ ░░▄ ░░░░░░▄ ░░▄ ░░▄ ░░░░▄ ░░░░░░▄
- ░░█▀░░█ ░░░░▄░░█ ░░█▀▀ ░░█ ░░█ ░░█▀▀▀ ░░█▀░░█
- ░░░░░░█ ░░█░░░░█ ░░█ ░░░░░░▄ ░░█ ░░█ ░░█░░░▄ ░░░░░░█
- ░░█▀░░█ ░░█ ░░░█ ░░█ ▀▀▀▀▀▀ ░█ ░█▀ ░░█ ░░█ ░░█▀░░█
- ░░█ ░░█ ░░█ ░░█ ░░░░░░▄ ░░█▀ ░░░░█▀ ░░█ ░░█
- ▀▀ ▀▀ ▀▀ ▀▀ ▀▀▀▀▀▀ ▀▀ ▀▀▀▀ ▀▀ ▀▀
-
-
- ░░░░░▄ ░░░░░░▄ ░░░░▄
- ░░█▀░░▄░░█▀░░█░░█▀░░▄
- ░░█ ░░█░░█ ░░█░░█ ▀▀
- ░░█ ░░█░░█ ░░█░░█ ░░▄
- ░░▄ ░░░░░█▀░░░░░░█ ░░░░█▀
- ▀▀ ▀▀▀▀▀ ▀▀▀▀▀▀ ▀▀▀▀
-
- (English documentation)
-
- ┌─────────────────────────────────────────────┐
- │ ANIVGA │
- │ a Sprite-Unit for TurboPascal V6.0 │
- │ by Kai Rohrbacher │
- │ Version 1.0 │
- └─────────────────────────────────────────────┘
-
-
- Purpose : Animation of sprites on a VGA's 320x200x256 mode and
- TurboPascal V6.0
- Author : Kai Rohrbacher
- Germany
- Internet: S_ROHRBACHER@IRAVCL.IRA.UKA.DE
- FIDO : 2:241/7503
- Language : TurboPascal V6.0
- Date : May 1991
-
- ---------------------------------------------------------------------
- Always remember: "I know my English spelling is bad, but if I used my
- own language you probably couldn't read it at all."
- -- Nico de Vries
- ---------------------------------------------------------------------
-
- 0. Table of contents
- ────────────────────
-
- 1. Prélude: Legal Notices
- 2. What is VGA?
- 3. Features and Restrictions of ANIVGA
- 4. "HELLO WORLD" - A First Example
- 5. How ANIVGA works
- 6. Tips, tricks and techniques
- 7. Credits
- 8. ANIVGA Reference Manual
-
-
- 1. Prélude: Legal Notices
- ─────────────────────────
-
- Okay, the boring stuff first...
-
- The author hereby disclaims all warranties relating to this software,
- whether expressed or implied, including without limitation any implied
- warranties of merchantability or fitness for a particular purpose.
- I will not be liable for any special, incidental, consequential, indirect
- or similar damages due to loss of data/damage to hardware or any other
- reason, even if I have been advised of the possibility of such damages.
-
- This programming toolkit is released as "freeware" by the author.
- It is however copyrighted and all rights and ownership are kept with the
- author. You may use it, copy it and give it to everybody as long as no
- modifications are made -- but don't try to sell it (or part of it)!
-
- Nevertheless, all programs you realize with this software package may be
- distributed freely - the only thing I ask you for is to mention the use
- of this toolkit in your program and to send me a copy of your program.
-
-
- 2. What is ANIVGA?
- ──────────────────
-
- ANIVGA is a powerful toolkit for the animation of sprites on any IBM (or com-
- patible) with a VGA card installed.
- It consists of one (big) TurboPascal V6.0-unit to be used by your applications
- and some utilities to simplify its use:
-
- ANIVGA.PAS - the source code of the animation unit
- MAKES.EXE - a simple spritemaker program (requires a mouse)
- GRAB.EXE - a TSR-program to "grab" sprites from other graphics
- UNLIB.EXE - a utility to break apart a library of sprites back into
- its individual sprite files
- DUMP_SPR.EXE - a "sprite dumper" which disassembles a (binary) sprite file into
- an ASCII-text
- *.* - documentation, examples, ...
-
- Copy these files into your TurboPascal-directory and compile ANIVGA.PAS to
- implement ANIVGA on your system - that's all.
-
-
- 3. Features and Restrictions of ANIVGA
- ──────────────────────────────────────
-
- Some of ANIVGA's features are:
-
- - flickerfree animation by a "page-flipping" algorithm and using the
- vertical retrace signal
- - sprite movement in any increments you want
- - arbitrary background image for the animation
- - full use of the VGA's 256-color mode
- - several sprite display methods available:
- - sprites can be written normally (covering underlying figures)
- - sprites can be declared to be transparent with regard to the background
- or other sprites pixel by pixel
- - sprites can change their color depending on the underlying background
- image (-> shadow function)
- - display methods can be different for each sprite
- - pixel precise hit-detection routine built in
- - correct clipping of sprites at the screen boundaries
- - up to 32767 different sprites
- - up to 500 sprites may be simultaneously active
- - maximal size of each sprite = 64k
- - maximal size of all loaded sprites only restricted by available memory
- - works with virtual coordinates in the range -16000..+16000
- - thus simple creation of horizontal/vertical "scrolling" games
- - scrolling background image, too
- - several supporting routines to: drawing lines (with built in clipping-
- algorithm), points and graphic-text (incl. clipping), automatic heap
- management for loading of sprites, sprite libraries, background images,
- processor-speed adjustment,...
-
- What ANIVGA does _not_ support:
- - EMS or XMS memory (too slow)
- - resolutions other than 320x200x256 (compatibility question)
-
-
- 4. "HELLO WORLD" - A First Example
- ──────────────────────────────────
-
- ANIVGA uses a non-standard 320x200x256 graphic mode, different from the BIOS-
- mode $13, but there should be no problems with all truly compatible VGA cards.
- To see if ANIVGA is compatible with your system and to get a first impression
- of its ease of use, compile the following simple program (you can find it on
- disk as file "EXAMPLE1.PAS"):
-
- (Remember to copy and compile ANIVGA.PAS in your TurboPascal-Unit-directory
- first)
-
- PROGRAM Example1;
- USES ANIVGA,CRT;
- CONST LoadNumber=42; {why not 42? - A "hello" to all Douglas Adam fans!}
- SpriteName='FLOWER.COD'; {Path and name of the sprite to load}
- Sprite1=0;
- Sprite2=5;
- VAR ch:CHAR;
- collide:BOOLEAN;
-
- BEGIN
- IF loadSprite(SpriteName,LoadNumber)=0
- THEN BEGIN
- CloseRoutines;
- WRITELN('Error: '+GetErrorMessage); halt(1)
- END;
-
- InitGraph;
-
- Color:=66;
- BackgroundLine(0,0,XMAX,0); BackgroundLine(XMAX,0,XMAX,YMAX);
- BackgroundLine(XMAX,YMAX,0,YMAX); BackgroundLine(0,YMAX,0,0);
- BackgroundOutTextXY(100,70,'Hello world!');
-
- SpriteN[Sprite1]:=LoadNumber;
- SpriteX[Sprite1]:=0; SpriteY[Sprite1]:=0;
-
- SpriteN[Sprite2]:=LoadNumber;
- SpriteX[Sprite2]:=XMAX SHR 1; SpriteY[Sprite2]:=YMAX SHR 1;
-
- WHILE KeyPressed DO ch:=ReadKey;
- Animate;
- REPEAT
- collide:=Hitdetect(Sprite1,Sprite2);
- if collide THEN BEGIN Sound(1000); Delay(5); NoSound END;
- if KeyPressed
- THEN BEGIN
- WHILE KeyPressed do ch:=UpCase(ReadKey);
- CASE ch OF
- 'I':DEC(SpriteY[0]);
- 'J':DEC(SpriteX[0]);
- 'K':INC(SpriteX[0]);
- 'M':INC(SpriteY[0]);
- 'A':DEC(StartVirtualX,10);
- 'S':DEC(StartVirtualX,10);
- END;
- IF POS(ch,'IJKMAS')>0 THEN Animate;
- END;
-
- UNTIL ch='Q';
-
- CloseRoutines;
- END.
-
- (Don't worry if you do not understand the whole program at once - it should
- only give you a first impression of ANIVGA's capabilities)
- If you run this program (make sure that the sprite file FLOWER.COD can be found
- by the program!) you should see a graphic consisting of two flowers, a rec-
- tangle showing the screen boundaries and the words "Hello world" near the
- middle of the screen.
- You can move the top left flower by using the keys "I","J","K","M".
- If you hit the other flower with the first one, the program will beep.
- Try out what happens if you move across the two words in the middle: obviously,
- the two leafs of the sprite behave somehow different: the black parts of left
- leaf are "transparent" in that the writing shines through it, while the black
- parts of the right leaf are "covering black".
- But the writing (which is written in the background image) won't be destroyed.
- As soon as you leave them, the words will be alright again.
- Move the sprite to the very left screen boundary - and move it even more to
- the left: you'll get the impression that it moves off the screen until it is
- totally offscreen.
- Hmmmm - how do we get it back? Sure, "K" will do, but press "A" instead: this
- will "pan" the whole screen 10 pixels to the left (think of that as if you
- could control an imaginary camera to slide to the left), "S" pans into the
- other direction (note the restriction of the program to non-scrolling back-
- ground at this point: the big rectangle and the words "Hello world" won't
- move because they are part of the so-called "static" background image).
- Now -using the "I","J","K" and "M" keys- bring back your sprite to the 2nd one
- and let them collide. Press "A" a few times to scroll them both offscreen.
- As you'll notice, the program will not stop beeping: it indicates that the two
- sprites collide, even if they are not visible to you!
- Okay, that should be enough for a first impression, so hit "Q" to quit the
- program, if you've finished wondering... :-)
-
- Run EXAMPLE2.PAS for a demonstration of "scrolling" background; the program is
- much the same as EXAMPLE1, but uses four different "tiles" to build the back-
- ground image. As before, you can use "I,J,K,M" to move your sprite along, but
- this time, you may scroll the whole scene (incl. the background!) with the
- "E,S,D,X" keys, too ("Q" quits, as before).
-
- EXAMPLE3.PAS shows (an extremely) simple use of the "Display_SHADOW" mode to
- display a graphical object: a sprite is used for its own shadow zone, simply by
- redrawing it with a little horizontal and vertical offset.
- Although this is a nice trick with many sprites (you don't have to design extra
- shadow sprites this way), it doesn't always work: note that there is one area
- in the flower which differs from what we would expect as shadow: this is
- because ANIVGA assumes that everything between the left- and rightmost point of
- a sprite belongs to the sprite's interior and will be drawn accordingly.
- (To circumvent this, one would have to draw one (or even several) especially
- designed "shadow zone" sprites for the flower, but we'll come to these aspects
- later)
- Pressing "P" draws 1000 randomly distributed points so you can better see the
- shadowing effect for single points.
- Finally, "C" copies part of the screen into memory (with GetImage() ) and
- pastes it somewhere else (with PutImage() ) while clipping off at the screen
- boundaries.
-
- EXAMPLE4.PAS is an example how to use "sprite cycles": there are six images in
- the sprite (library) file HANTEL.LIB which become "glued" together to form one
- sprite cycle.
- App. one hundred copies of this sprite are then animated on the screen with
- maximum animation speed and again, you can scroll the whole screen area with
- the keys "E","S","D","X". When you do, you will note that as more and more of
- the sprites gets scrolled offscreen, the remaining sprites will rotate faster.
- Pressing the space bar will toggle between fastest animation (no time limit)
- and an animation rate of 200ms per frame.
- You can play around with this value to find out an "optimal" time for your PC
- and this program:
-
- very small: program will show the same symptoms as mentioned above (being
- faster for every sprite offscreen)
- .
- .
- .
- very big : program will slow down even when all sprites are onscreen
-
- Somewhere between lies a value where the animation doesn't get slowed down when
- all sprites are onscreen (=max. work for ANIVGA), but stays at the same speed
- for all other cases (=less work for ANIVGA).
-
-
- 5. How ANIVGA works
- ───────────────────
-
- (It would be _impossible_ trying to cope every detail of ANIVGA, but I'm sure
- you will get the basic ideas of ANIVGA very soon.)
-
- As already mentioned, the program uses a "tweaked" VGA-graphic mode: the VGA
- is programmed in a way to give 4 graphic pages at a resolution of 320x200
- pixels in 256 colors ("they said it couldn't be done, but here it is!..."),
- numbered 0..3.
- Page 0 and 1 are used for the display, page 2 holds the "normal" background
- image and page 3 can contain so-called "tiles" which can be used to build a
- huge background image in "scrolling" background mode.
- The basic idea of the "page flipping" scheme used is that: do everything (era-
- sing the old graphic page, draw sprites/lines/pixels/text) on a graphic page
- invisible to the user while showing him a completed page on the screen.
- Then, if finished, "flip" the page, thus making the new, completed page visible
- and the old page to the invisible one. Now start creating the next image on
- this new invisible page - and so on.
- "Erasing" the old image means: overdraw it completely with the background image
- stored in page 2 (or 3), so one could write in pseudo code:
-
- ...
- REPEAT
- show page 0 to user;
- fill (invisible) page 1 with contents of page 2;
- draw new sprites and all other stuff on page 1;
- show page 1 to user;
- fill (invisible) page 0 with contents of page 2;
- draw new sprites and all other stuff on page 0;
- UNTIL DOOMSDAY
- ...
-
- You as the programmer doesn't have to think much about this mechanism, the
- routines keep track of the page flipping automatically: the global variable
- "PAGE" always holds the number of the page which is invisible (and thus:
- the page to be drawn on). Therefore, we say that PAGE holds the "actual page"
- number and 1-PAGE is the page visible to the user.
- Most of the procedures and functions of the animation package adjust themselves
- to the appropriate page; there are only a few situations where you have to be
- aware of this mechanism, mostly when drawing pixels or to create special
- effects.
-
- The whole package is "table driven". That means, the interface to the user
- consists of some tables in which you specify your sprites to be drawn:
- You store into this tables which sprites to draw ("SpriteN[]") and their
- coordinates (in "SpriteX[]" and "SpriteY[]").
- After this, a call of the main routine "Animate()" gives back control to the
- animation routines, which update the graphic screen accordingly:
-
- ...
- REPEAT
- update SpriteN[]-table:
- deactivate sprite i by storing a "0" into SpriteN[i] or
- activate a sprite k by storing k in an unused SpriteN[]-entry or
- let all the other SpriteN[]-entries as they were last cycle
- FOR ALL SpriteN[i]<>0 DO
- IF SpriteN[i] should change its coordinates
- THEN update (SpriteX[i],SpriteY[i]) accordingly
- call Animate() to draw image and display it
- UNTIL end-of-computer-life
- ...
-
- You should notice that there are two kinds of "sprite numbers" which should
- not be mixed up: one is a spriteLOAD number and represents a handle to the
- (physical) sprite data, while the other (normally termed "sprite number") is
- a logical number to address this sprite data.
- In the pseudo code given above, "k" is the spriteLOAD number (it is a number
- given at load time) and the index "i" in SpriteN[i] is the sprite number.
- Note that "k" is a unique value: you can think of it as a NAME of the sprite
- data loaded (e.g. you could name the FLOWER.COD - data as "123" when loading
- it: there can't be another sprite with the same LOAD-number). On the other
- hand, there could be a hundred flowers on the screen: just choose hundred
- different sprite-table entries (=sprite numbers), e.g. SpriteN[100]..
- SpriteN[199] and store "123" in each of them!
- Whenever you are unsure if you (or I) are speaking of a "sprite number" or a
- "spriteLOAD number", remember that:
-
- ■ A sprite number can hold values in the range 0..NMAX and is an index of
- the tables SpriteX[], SpriteY[] and SpriteN[].
- ■ A spriteLOAD number can hold values between 0..LoadMax and is assigned
- as a "name" to the sprites' physical loaded data; a "0" as load number is
- reserved for "inactivate sprite"
-
-
- The world ANIVGA knows is 32000 pixels wide and high, numbered -16000..+16000
- on each axis. Because your graphic screen consists of only 320 by 200 points,
- (ranging from 0..XMAX and 0..YMAX in the x- and y-axis, respectively; (0,0) is
- the upper left corner, (XMAX,YMAX) the lower right one) you can only see a
- small part of this world, but ANIVGA does not distinguish between the visible
- and invisible parts of the world. If, for example, two sprites collide, the
- routine "HitDetect()" will find out, even if this collision occurs offscreen.
- Thus you can think of your graphic display being a "camera" to the real world:
- your actions can take place everythere in this virtual world, but you see only
- the part displayed by your camera; if you wish to see another part of your
- world, you have to move this imaginary camera to that place.
- In ANIVGA, you can do this by changing the values "StartVirtualX" and
- "StartVirtualY" which hold the upper left corner of the visual window. As an
- example, let (StartVirtualX,StartVirtualY) be (1000,500): then on your screen
- you will see the part of the world which ranges from coordinates (1000..1319)
- and (500..699) in X- and Y-directions, respectively.
-
-
- 6. Tips, tricks and techniques
- ──────────────────────────────
-
- There would be a lot of things to say and most of them will be mentioned in the
- following "Reference Manual". Nevertheless, it seems reasonable to repeat them
- in a more concentrated form here, although this happens to make this chapter a
- real topsyturvydom...
-
- a) The ERROR-concept: if an error occurs in one of ANIVGA's routines, the
- global variable ERROR will be set accordingly. This gives you the freedom
- either to check this variable each time you called a routine - or ignore it
- for improved speed.
- As a rule of thumb, you should always check this variable while your program
- is still in the testing phase - and "comment out" these sections when you
- are through with debugging. (Conditional defines are great for that job!)
- Note that there are some routines that do not set ERROR at all (like Screen,
- GetPixel, PageGetPixel, PagePutPixel), either because in some special cases,
- "nice" tricks can be played with "faulty" parameters or because of severe
- speed improvements! For example, if you are going to read a 5000 pixel area
- from the screen with PageGetPixel(), it would be crazy to check 5000 times
- whether the "page" given to read from is valid or not.
-
- b) Pixel-drawing routines: basically spoken, there are three sorts of graphic
- data objects in ANIVGA: sprites, pixels and background images.
- Because of ANIVGA's working scheme, all routines handling pixels (PutPixel,
- PagePutPixel, Line, PutImage,...) must be used in a special form:
- - If you use them to "draw" into the background page, this can only be done
- when using background mode STATIC (because in mode SCROLLING, the back-
- ground is stored in a compressed format one can't access directly).
- - Drawing into the background page in mode STATIC is fine (that's the main
- advantage of this mode compared with mode SCROLLING), and the best time to
- do it is _before_ calling Animate(), because changes to the background
- image will then be visible with the call to this routine.
- - Drawing "on the monitor screen" will be visible exactly for one animation
- cycle, that is: until the next call to Animate(). For this reason, you
- must do this changes _after_ calling Animate() and at the _visible_ page
- 1-PAGE (not the _actual_ page PAGE itself).
-
- It is not that difficult as it may sound at first glance; for example:
- ...
- REPEAT
- read_user_inputs; compute_necessary_actions;
- do_all_changes_to_the_background_image;
- do_all_changes_to_the_sprites;
- Animate();
- do_all_changes_to_the_visible_screen; {e.g.: Line(0,0,XMAX,YMAX,1-PAGE)}
- UNTIL user_wants_to_end_application
- ...
-
- This way, after having called Animate(), the changes to the background
- (and your sprites) will be visible (because Animate() has generated an
- appropriate picture) and your changes to this image with the pixel-
- drawing routines will be visible "at once".
- That image will then stay visible until the next call to Animate().
- (Simply spoken, you let Animate() generate and display a picture and then
- do some changes to the picture while it is diplayed)
- - Because of unavoidable memory restrictions, ANIVGA can't store pixels
- drawn offscreen: if ANIVGA sees that points/lines lie outside the visible
- screen, it just does nothing at all; in other words, you can't draw a line
- outside the screen and "scroll it in" five minutes later! (You would have
- to define the line as a sprite instead, because sprites are the only
- objects stored independently).
-
- c) Coordinates: Throughout all routines, ANIVGA works with _virtual_ coordi-
- nates (that is, values in the range xε[-16000..+16000], yε[-16000..+16000]),
- but sometimes you will have to address _absolute_ coordinates (in the range
- xε[0..XMAX], yε[0..YMAX]), so you have to transform virtual coordinates into
- absolute coordinates (or vice versa), which is _very_ easy:
-
- virtual coordinates -> absolute coordinates:
- Xabsolute := Xvirtual - StartVirtualX
- Yabsolute := Yvirtual - StartVirtualY
-
- absolute coordinates -> virtual coordinates:
- Xvirtual := Xabsolute + StartVirtualX
- Yvirtual := Yabsolute + StartVirtualY
-
- d) Background / valid pages: Many routines expect a graphic page number as
- parameter. As mentioned under b), BACKGNDPAGE is valid only when you use
- background mode STATIC. Nevertheless, you can draw to this page even when
- you are using background mode SCROLLING without getting an error
- "Err_InvalidPageNumber" (although you are _strongly_ discouraged to do so)!
- That's because you can play some tricks on ANIVGA this way, provided that
- you do know _exactly_ what you (and ANIVGA) are doing, but this "feature"
- will probably be cut off in future versions of this program.
- (Note that this doesn't mean that you can't switch between STATIC and
- SCROLLING backgrounds during runtime! - It only says that you can't use
- the two background pages _in parallel_ (=at the same time)!)
-
- e) Display objects at the same abolute screen position:
- Let us assume you want to display a score at the upper right corner of the
- screen; that's not hard when using STATIC background: just define your
- score as a sprite and choose an appropriate coordinate pair.
- In SCROLLING mode, your score would scroll away, too, so you must tie it to
- absolute screen coordinates, as said in c), but there is a simple rule which
- can be derived from the equation
-
- absolute_coordinate := virtual_coordinate - StartVirtual_value
-
- To ensure that the absolute (=screen) coordinate stays the same, you have to
- balance out changes done to the StartVirtual-variables like this: whenever
- you increase/decrease StartVirtual? by some amount delta, increase/decrease
- your score-coordinates by the same amount delta!
- (This results in: new_coord := virtual_coord±delta - (StartVirtual±delta)
- = virtual_coord - StartVirtual = old_coord as wanted)
-
- f) Displaying scores: another way to display a score without defining it as a
- sprite would be to simply draw it to the screen with the pixeldrawing rou-
- tines or OutTextXY():
- ■ draw it to the visible page (1-PAGE) each time after having called
- ANIMATE()
- ■ draw it to the background page BACKGNDPAGE
- The last method is applicable only in background mode STATIC and you have
- to restore the background image in the used area manually, but has the ad-
- vantage that you must redraw your score only when it really changed (instead
- of every animation cycle as with the first method). One way to accomplish
- that would be to use the GetImage() and PutImage() routines:
- ...
- build background image;
- use GetImage() to get a copy of the background area which will be overdrawn
- by the score;
- ...
- main_loop:
- IF new score has to be displayed
- THEN BEGIN
- use PutImage() to restore old background area underneath the score;
- use OutTextXY() to write new score into the background image
- END
- ...
-
- g) Speed: It is hard to predict the speed of animations, because that is merely
- determined by the speed of your VGA card, not your computer's CPU clock
- rate! E.g., a program runs faster on my old AT (8MHz) than on a fast (25
- MHz) 80386 machine - only because of a better VGA card installed in the AT!
- Stated otherwise, if you use a computer with "enough" CPU-power, you won't
- have to think much about "should I use STATIC background instead of SCROL-
- LING for improved speed?", because it won't matter anyway!
- The break even point, where the VGA-card's bottle neck becomes the limiting
- factor depends largely on your application (and your VGA-card, of course),
- but as a rule of thumb, clock speeds faster than 12MHz won't improve your
- program speeds *linearly* any further:
-
- animation ^ ______
- speed │ ___----
- │ /
- │ /
- │/
- ┼─────┬───────────> clock rate
- break-
- even point
-
- Note that your programs will still profit from faster CPU's, but that is due
- to faster computation of all routines not limited by accessing the video
- RAM; even on the fastest clones, the IBM-bus-clock-rate is not faster than
- 10MHz -- and this limits accessing the VGA card: sad, but true...
-
- g) DMA access: Quite a long time, I tried to speed up animation rates by using
- the DMA-chip in parallel to the CPU: while the CPU is running your program,
- the DMA should move around memory.
- Unfortunately, I had to find out that most computers don't like DMA memory-
- to-memory transfers at all and those who do don't work when addresses used
- reference the video RAM area (I can't explain why this is the case).
- If someone out there has successfully worked with the DMA chip this way, I
- would be glad to know!
-
-
- 7. Credits
- ──────────
-
- Honour to whom honour is due! Although most of the routines are mine, two of
- the utility programs (also written in TP6.0) use stuff from other Freeware
- authors:
-
- - The GRAB-utility uses Ken Pottebaum's TSR-unit TSRUNIT.ZIP and
- - The MAKES-designer uses John Bridges' BGI-driver SVGA256.BGI (for the VGA's
- 320x200x256 mode $13) from his SuperVGA-driver package SVGABGI3.ZIP
-
- (Both programs are available at the SIMTEL20-servers)
-
- Thanks to them for supporting the Freeware-concept, their spirit made it
- possible to distribute this program as Freeware, too!
-
-
- 8. ANIVGA Reference Manual
- ──────────────────────────
-
- This reference manual lists all routines, variables, constants and a lot of in-
- formational stuff concerning ANIVGA in alphabetic order.
- Don't get frightened about the amount of informations given; in normal appli-
- cations you will need only a few of them!
-
-
- ABSOLUTE COORDINATES - information
- ──────────────────────────────────
-
- See : coordinates
-
-
- Animate - procedure
- ───────────────────
-
- Function : Performs a complete animation cycle
-
- Declaration: {$F+} PROCEDURE Animate {$F-}
-
- Description: A call to Animate() clears the invisible graphic page by copying
- the contents of the background image into the actual drawing
- page (specified by variable PAGE).
- Then all active sprites (SpriteN[i]<>0) in the visible window
- (determined by StartVirtualX and StartVirtualY) are drawn in the
- style and at the coordinates given by the user.
- After that, the routine waits for a vertical retrace to reprogram
- the VGA adapter to flip the display pages, making the completed
- image visible and changes PAGE to point to the new, invisible
- graphic page.
- Finally, the procedure looks how much time passed since the last
- animation cycle and if this time is less than that set by
- SetCycleTime(), the program waits accordingly.
-
- Note : This procedure is the kernel routine which has to be called every-
- time when you have set all data for a new animation frame.
-
- See also : PAGE, SetCycleTime, StartVirtualX, StartVirtualY
-
-
- BackGndPage - constant
- ──────────────────────
-
- Function : Holds the page number of the backround page
-
- Declaration: CONST BACKGNDPAGE=2;
-
- Description: When using background mode STATIC, BackGndPage specifies the page
- number of the background image for the animations to be used.
-
- Note (!) : Use of this constant only makes sense when using background mode
- STATIC!
-
- See also : ScrollPage, Background
-
-
- Background - information
- ────────────────────────
-
- The term "background" specifies a graphic image in front of which all anima-
- tions take place.
- There are two sorts of background in ANIVGA: SCROLLING background and STATIC
- background, which you choose with SetBackgroundMode().
-
- As its name states, a STATIC background cannot be scrolled: it consists of a
- 320x200 pixels picture.
- This background picture is stored in the graphic page numbered BACKGNDPAGE.
- At the very start of every animation cycle, the routine Animate copies that
- picture into the actual drawing page, thus erasing old stuff on that page and
- building the basis for the new image.
- As a normal bitmap picture, it is 320x200=64000 bytes in size. If you use the
- GRAB-Utility or the WritePage()-Routine to save an image, a three byte header
- is put ahead of the information, thus extending the size to 64003 bytes.
-
- The second background sort is called SCROLLING: like ANIVGA's virtual coor-
- dinates, you can define a huge background image and scroll over it.
- Unfortunately, it is impossible to hold a complete background picture in
- memory: you would need 32000*32000=1024000000 bytes RAM (!) to do that.
- Instead, ANIVGA uses a "tiling" mechanism: tiles are small pictures (16x16
- pixels) which can be combined freely to build the background image.
- You can use up to 256 different tiles and "pin" them on an background area of
- up to MaxTiles (=10000) tiles; everything outside of this background area will
- be assigned to tile no. 0 automatically.
- For example, let us assume that you use only scrolling in the y-coordinate
- axis, 16 screens in total: thus, your x-coordinates reach from 0 to 319 and
- your y-coordinates from 0..(16*200-1)=5119, which gives an area of 320*5120
- =1638400 pixels.
- This is equivalent to (320/16)*(5120/16)=20*320=6400 tiles (remember: each
- tile consists of 16x16 pixels!).
- So you would define the scroll range for the background area needed with
- SetBackgroundScrollRange(0,0,319,5119) and start "painting" your background:
- You could design up to 256 different tiles and use them to assemble your
- background image (=those 6400 tiles).
- Most often, only a few are needed, because the background image isn't that
- dramatically different all over the place. For simplicity, let's assume that
- you need only 20 different tiles, numbered 0..19 respectively in the following
- order to build your background image:
-
- (0,0) (319,0)
- ┌────────┬────────┬────────┐ ┌────────┬────────┬────────┐
- │ │ │ │ │ │ │ │
- │ 0 │ 1 │ 2 │ ... │ 13 │ 14 │ 15 │
- │ │ │ │ │ │ │ │
- ├────────┼────────┼────────┤ ├────────┼────────┼────────┤
- . . . . . .
- . . . . . .
- . . . . . .
- ├────────┼────────┼────────┤ ├────────┼────────┼────────┤
- │ │ │ │ │ │ │ │
- │ 0 │ 1 │ 2 │ ... │ 13 │ 14 │ 15 │
- │ │ │ │ │ │ │ │
- └────────┴────────┴────────┘ └────────┴────────┴────────┘
- (0,5119) (319,5119)
-
- Now all you have to do is to tell ANIVGA that layout with the PutTile command:
-
- {assuming SetBackgroundScrollRange(0,0,319,5119) has been set}
- number:=0;
- y:=0; {better: y:=BackY1}
- REPEAT (things would become easier if Pascal would know a STEP-command...)
- x:=0; {better: x:=BackX1}
- REPEAT
- PutTile(x,y,number);
- number:=(number+1) MOD 16;
- inc(x,16);
- UNTIL x>319; {better: x>BackX2}
- inc(y,16);
- UNTIL y>5119; {better: y>BackY2}
-
- That's it! (It is better to use the (global defined) "Back..."-variables, set
- by the former SetBackgroundScrollRange()-call, because ANIVGA has to adjust
- values on multiples of 16, see SetBackgroundScrollRange()/Back?? for more
- details).
-
- So then, why should one use STATIC backgrounds after all when there is such a
- powerful instrument like SCROLLING backgrounds?
- There are two simple answers: speed and simplicity! - First, SCROLLING back-
- grounds take a lot of work to compute, which slows down animations (unless you
- have a fast machine, because then the VGA's memory access time becomes the
- limiting factor). Second, it is easy to do some "tricks" on static backgrounds:
- draw a line in the static background page and >zap!< starting with the next
- animation cycle, it will be visible for all times. Stated otherwise, when using
- scrolling background, you cannot use drawings to the background image, because
- it simply doesn't exist explicitly, you are restricted solely to "tiles" and
- "sprites"! (On the other hand, you can play nice tricks on scrolling background
- by changing single tiles...)
- So consider carefully what mode you are going to use for your application!
-
- See also : BACKGNDPAGE, BACKGNDADR, WritePage, LoadPage, WriteBackgroundPage,
- LoadBackgroundPage, SetBackgroundMode, LoadTile, Tile
-
-
- BackgroundGetPixel - function
- ─────────────────────────────
-
- Function : Reads a background pixel's color
-
- Declaration: {$F+} FUNCTION BackgroundGetPixel(x,y:INTEGER):BYTE; {$F-}
-
- Description: This routine will return the color value of the specified point
- with virtual coordinates (x,y) in the background image.
- If the corresponding absolute coordinates lie outside the screen,
- zero (= black) will be returned.
-
- Note : Use of this routine works only when using background mode STATIC!
- It might look strange to use virtual coordinates then, although
- the background is said to be static (= non-scrollable) and hence
- restricted to absolute coordinates anyway, but it is often con-
- venient to use an uniform notation and it is easy to convert co-
- ordinates accordingly (see "coordinates" for more about that).
-
- See also : coordinates, GetPixel, PageGetPixel
-
-
- BackgroundLine - procedure
- ──────────────────────────
-
- Function : Draws a line on the background page
-
- Declaration: {$F+} PROCEDURE BackgroundLine(x1,y1,x2,y2:INTEGER); {$F-}
-
- Description: To draw a line on the background page (thus alterating the back-
- ground), you can use this procedure. Like the similiar Line()-
- routine, it uses virtual coordinates, too.
- If necessary, the line will be clipped down to its visible part
- (using a special Sutherland-Cohen algorithm).
-
- Note : Use of this routine only makes sense when using background mode
- STATIC!
-
- See also : Line, coordinates
-
-
- BackGroundMode - variable
- ─────────────────────────
-
- Function : Holds the actual choosen background mode
-
- Declaration: VAR BackgroundMode:BYTE;
-
- Description: Using SetBackgroundMode(), you can select one of the possible
- background modes STATIC or SCROLLING. BackGroundMode stores this
- value.
-
- Note (!) : Only read this value, never change it directly!
-
- See also : Background, SetBackgroundMode
-
-
- BackgroundOutTextXY - procedure
- ───────────────────────────────
-
- Function : Writes a textstring to the background page BACKGNDPAGE
-
- Declaration: {$F+} PROCEDURE BackgroundOutTextXY(x,y:INTEGER; s:STRING); {$F-}
-
- Description: This routine is exactly the same like OutTextXY() (see there), but
- it writes the string into the background page (so it will be visi-
- ble permanently).
-
- Note : Use of the routine only makes sense if STATIC is used as
- background mode.
-
- See also : GraphtextColor, GraphtextOrientation, GraphtextBackground,
- OutTextXY, background
-
-
- BackgroundPutPixel - procedure
- ──────────────────────────────
-
- Function : Plots a point into the background page
-
- Declaration: {$F+} PROCEDURE BackgroundPutPixel(x,y:INTEGER; color:BYTE); {$F-}
-
- Description: (x,y) specify the virtual coordinates of the point to be drawn in
- color "color". If this point lies onscreen (i.e.: its _absolute_
- coordinates are between (0,0)..(319,199)), it will be drawn on the
- background page BACKGNDPAGE (and become visible starting with the
- next animation cycle).
-
- Note (!) : - Use of this routine makes sense only when using background mode
- STATIC!
- - This routine works with virtual coordinates! - Although this
- seems silly at first glance (because in STATIC mode, background
- coordinates are always restricted to (0,0)..(319,199)), it
- appears to be handy in many situations. If you actually want to
- address points absolute coordinates (a,b), you can call this
- routine with coordinates (a+StartVirtualX,b+StartVirtualY)
- instead.
- - Because of ANIVGA's working scheme, you probably want to call
- this routine _before_ calling Animate(), so that changes of the
- point will be visible as soon as possible.
-
- See also : PutPixel, PagePutPixel, background, coordinates, How ANIVGA works
-
-
- BACKX1, BACKX2, BACKY1, BACKY2 - variables
- ──────────────────────────────────────────
-
- Function : Hold the background image boundaries in background mode SCROLLING
-
- Declaration: BackX1,BackY1,BackX2,BackY2:INTEGER;
-
- Description: When background mode SCROLLING is to be used, you have to define
- a scrolling area (with SetBackgroundScrollRange()). Due to inter-
- nal management restrictions of ANIVGA, the boundaries of this area
- must fall on coordinates which are multiples of 16 ("on a grid
- with mesh 16").
- If the values you supply don't fulfill this restriction, ANIVGA
- adjusts them automatically to do so and stores them to these
- variables for further use.
-
- Note : The only reason these variables are visible to you are that it
- could be necessary for you to notice adjustments ANIVGA did;
- so: only read this values, never change them directly!
- (Look at "background" for an example).
-
- See also : background
-
-
- CloseRoutines - procedure
- ─────────────────────────
-
- Function : Terminates ANIVGA
-
- Declaration: {$F+} PROCEDURE CloseRoutines; {$F-}
-
- Description: Calling this routine switches back from ANIVGA's special graphic
- mode into the graphic or text mode previously set.
-
- Note : This should always be the last call to a routine of ANIVGA in your
- programs.
-
- See also : InitGraph
-
-
- COLLISION-DETECTION, CONCAVE, CONVEX - information
- ──────────────────────────────────────────────────
-
- A graphical figure can be classified by its outline into one of two groups,
- called "concave" or "convex" figures.
- To motivate this mathematical notion >eh, don't get frustrated...<, regard
- your sprite only given by its "outmost" points, which connected together shape
- the figures boundaries.
- The figure is called "convex" :<=> every pair of arbitrarily choosen points
- on this boundary build a line which is totally inside (or at least on the
- boundary of) the figure:
- ┌──────┐ This rectangle is "convex", because whenever you choose two points
- │ │ on its boundaries and connect them, the resulting line lies com-
- └──────┘ pletely inside (or on the boundary) of the rectangle itself.
-
- ┌──────┐ On the other hand, this figure would be "concave", because if you
- └─┐ ┌─┘ choose the top-right and bottom-right corner (say) and connect them,
- ┌─┘ └─┐ then the middle part of the resulting vertical line lies outside the
- └──────┘ figure.
-
- That is (in a very lax form) the _mathematical_ definition of these terms, but
- ANIVGA completely deals with either horizontal or vertical lines, so that an
- extension of these terms can be made:
-
- A sprite is called "horizontal concave" ("vertical concave"), if a horizontal
- (vertical) line connecting two points of the sprite's boundary can be found
- so that parts of this line lies outside the sprite; if the sprite is not hori-
- zontal (vertical concave), it is "horizontal convex" ("vertical convex").
-
- In that sense, the second of the figures above is "vertical concave", but
- "horizontal convex"!
- (Notice that figures which are concave in the pure _mathematical_ sense are
- sometimes treated as convex by this definition, as this cross:)
- ┌─┐ (If you use either a horizontal or vertical "scan line" sweeping
- ┌─┘ └─┐ throughout the cross, there will be never more than one part of
- └─┐ ┌─┘ the "scan line" which belongs to the figure; you can use this
- └─┘ principle as a second definition for horizontal/vertical convex)
-
- This terminology comes in handy when describing some mechanisms of ANIVGA: a
- sprite is drawn LINEwise. For this, every point between the leftmost and right-
- most point of a sprite's line is considered to be an _inner_ point of the
- sprite, thus ANIVGA assumes a horizontal convexity! If your sprite isn't, like
- this one...
- ┌─────┐ ...and the points between the two "legs" of this sprite shall still
- │ ┌─┐ │ be treated as "transparent" (assuming they have been defined with
- │ │ │ │ color "black" (=0)), you must use display mode "Display_NORMAL",
- │ │ │ │ because the "Display_FAST" mode would treat them as belonging to the
- └─┘ └─┘ sprite itself and draw them as "covering" black.
-
- (To state it otherwise: whenever your sprite is (at least) horizontal convex
- and you don't need the feature of transparent parts inside the sprite, you
- can use the "Display_FAST" mode without any loss of accuracy in the sprite
- display)
-
- Tip: the spritemaker program MAKES allows to display a sprite's horizontal
- boundaries, which makes it easier for the beginner to decide about that
- figure's convexity. But whenever you are unsure, you still can use mode
- "Display_NORMAL" for drawing it.
-
- ---
-
- Things get a bit more tough when deciding if two sprites collide or not (which
- is an important task): in difference to many sprite toolkits, ANIVGA doesn't
- use a "mask" approach, which makes sprites big and collision detection slow.
- Instead, ANIVGA uses a sprite's outline to decide whether two sprites collide.
- For that, it computes for every line (column) of the overlap region of the
- sprites' surrounding rectangles, whether the sprites overlap horizontally
- (vertically) and says "collision!" only if there are intersections in both
- directions. In pseudo code:
-
- IF smallest_box_around(sprite1) doesn't intersect smallest_box_around(sprite2)
- THEN no_collision
- ELSE BEGIN
- compute the lines and columns for which the 2 sprite rectangles overlap
- FOR every such line compare -with the help of the sprite boundaries- if
- the corresponding lines overlap
- FOR every such column do the same check
- ONLY_IF there is an intersection in at least one line AND one column
- THEN collision!
- ELSE no_collision
- END
-
- If you think a byte (=8 bits...) about this algorithm, you'll see that it can
- lead to misdetection, in that the algorithm says "collision!", although there
- is none (but it still guarantees that if there _is_ a collision, the alg. will
- detect it) as in the following example:
- ┌─────┐
- └───┐ │
- ┌────────┐ │ │
- │ ┌────┐ │ │ │
- │ │ ┌─┐│ │ │ │ <─ In this line there is a "horizontal collision" (that is,
- └─┘ │ │└─┘ │ │ the two sprites overlap in their horizontal dimension)
- │ └────┘ │
- └────────┘ ┌─ In this column there is a "vertical collision"
- ^───────┘
-
- To state things without a proof here, such an (unavoidable) misdetection is
- only possible, if at least one of the two sprites is neither horizontal nor
- vertical convex!!!
-
- Even then, it takes special constellations (as the one above) to produce such
- an error, so that in praxis, it is very unlikely for such an error to occur.
-
-
- Color - variable
- ────────────────
-
- Function : Determines the actual drawing color
-
- Declaration: VAR Color:BYTE;
-
- Description: Various drawing routines use this global variable to determine
- which color should be used.
-
- Note : ANIVGA uses the standard color table of the 256-color mode $13.
-
- See also : -
-
-
- ColorTable - type
- ─────────────────
-
- Function : Supply a data type for self-defined "Shadow Tables"
-
- Declaration: TYPE ColorTable=ARRAY[0..255] OF BYTE;
-
- Description: If you want to use a different color look-up-table for your
- sprites in display mode Display_SHADOW than can be achieved with
- SetShadowTab(), you must build a table like this.
- Each entry gives the color which should be used to replace the
- original color with that index, i.e.: if c is of type ColorTable
- and c[5]=9, this means that every point of your sprite which is to
- be drawn over a pixel with color 5 should replace that pixel with
- color 9.
- You can find an example how to activate such a "home-brew" table
- at "ShadowTab".
-
- Note : -
-
- See also : ShadowTab, SetShadowTab, Display modes
-
-
- COORDINATES - information
- ─────────────────────────
-
- ANIVGA has to deal with two kinds of coordinates: "virtual" and "absolute" ones.
- An absolute coordinate lies in the range 0..319, 0..199 for the x and y values,
- respectively. It names a unique point on your graphic screen.
- However, ANIVGA doesn't restrict animations to take place on the visible
- graphic screen: its routines deal with coordinates in the range -16000..+16000
- in each direction, called "virtual coordinates".
- The picture you view while ANIVGA's routines are running is a window of that
- virtual screen, 320 points wide and 200 points high.
- Naturally, the graphic hardware only knows absolute coordinates and thus,
- ANIVGA has to transform virtual in absolute coordinates. It does this with the
- help of the two variables StartVirtualX and StartVirtualY which together speci-
- fy the starting point of the upper left corner of your actual screen window;
- e.g. if (StartVirtualX,StartVirtualY) was (1000,2000) then you would look at
- the part of ANIVGA's world which consists of the 320x200 region with the coor-
- dinates xε(1000..1319) and yε(2000..2199).
- Note that there is one severe restriction, though: because it is absolutely
- impossible to hold a complete "virtual" screen bitmap for ANIVGA's world in
- memory (it would need app. 1GB RAM!), all drawing commands only take place on
- the visible screen.
- This means that you can't draw lines, points or any other objects which are
- _not_ sprites outside the visible window that become visible, when you scroll
- your window over to that part of the virtual screen. For example, if you draw
- a point somewhere outside your visible window (say at (-10000,1234) while your
- visible window starts at (500,900)) and pan to that region afterwards (by set-
- ting (StartVirtualX,StartVirtualY)=(-10100,1200) or something like that), you
- won't see that point: it is stored nowhere.
- (The only way to circumvent this is to define the point as a sprite and set its
- coordinates (SpriteX[],SpriteY[]) to (-10000,1234), because sprites are the
- only objects which the system stores!).
-
- More general:
- Because there is _no_ complete virtual screen, all information drawn outside
- the coordinate range visible at the moment will be lost and all information
- read in from these "offscreen" pixel positions will be zero (= black).
- For that reason it may seem strange for some routines that were restricted in
- their use to the "real" (= absolute coordinate) screen region to use virtual
- coordinates inspite (e.g.: GetImage, BackGroundGetPixel,...), but this was done
- intentionally, because it leaves room for further improvements: if it should be
- possible some day to store a complete virtual screen image, there will be no
- changes necessary in ANIVGA's syntax.
- Meanwhile, it is simple to transform absolute and virtual coordinates into each
- other whenever necessary, using the following equivalence:
-
- virtual X-coordinates - StartVirtualX = absolute X-coordinates
- virtual Y-coordinates - StartVirtualY = absolute Y-coordinates
-
- As a result: virtual coordinates lie in the range -16000..+16000, the start of
- the visible part is defined in StartVirtualX and StartVirtualY and only sprites
- can be "scrolled in" into the visible screen, while all other objects are
- "lost".
-
-
- Display modes - information
- ───────────────────────────
-
- ANIVGA is able to display a sprite in several "modes". This describes how the
- sprite's data should be handled when drawing the sprite to the screen. Up to
- now, there are three modes:
- - Display_NORMAL
- - Display_FAST
- - Display_SHADOW
- This mode is linked to a sprite's physical data by creation of the sprite with
- the spritemaker program (and defaults to Display_NORMAL), but can be altered
- once the sprite is loaded into memory with the procedure SetModeByte().
-
- Note that the display mode information is part of the _physical_ sprites (that
- is, the memory image of the bytes loaded at the beginning), not the _logical_
- sprites (the "handles" in the SpriteN-array to this physical data). For that
- reason, a change of the display mode of a sprite with spriteLOAD number 123
- (say) will affect _all_ sprites of type 123 (= all entries in SpriteN[] with
- value 123). This is intended, because the display mode is a piece of informa-
- tion reflecting the sprite's physical structure.
-
- In mode "Display_NORMAL" you can think of a sprite as a picture with holes at
- the places where its pixels have color 0: when displayed, all the parts of the
- sprite with color<>0 will cover (paint over) the screens original pixels, but
- the pieces with color=0 will act like "window panes": the original contents of
- the screen remain visible there.
- This mode is useful for all kinds of sprites which have such opaque holes in-
- side themselves: cars/planes/houses or other objects with window panes, but
- also all "concave" sprites. Note that black, covering parts must be realized
- with a dark color<>0, for example color 16.
-
- "Display_FAST" is a bit (but not that dramtically) faster than the last method,
- because it doesn't know of a special color: all sprite data is treated equally
- and stored to the screen at once. For that, all parts of the sprite are
- covering. (But note that a sprite consists only of the points inside and on its
- boundaries: all the points of the smallest box surrounding it -that is the way
- a sprite is stored- doesn't matter).
- You will use this mode whenever you have sprites which meet the following re-
- quirements: they are "convex" and don't have any transparent parts inside them-
- selves.
-
- "Display_SHADOW" is a tribute to the fact that one often needs some kind of
- shadowing to give the impression of an freefloating object or other pseudo
- 3D-effects. In this mode, the sprite's real colors are insignificant, only its
- boundaries and the actual contents of the screen where the sprite shall be
- drawn are important. The color of every sprite point is determined by the color
- of the appropriate screen point. The color of these points are translated by
- the lookup table ShadowTab into darker ones.
- If you want to give a sprite a shadow zone, then you must divide your sprite
- into two ones: one building the sprite itself and a second one to realize only
- that shadow area, and compose them with appropriate coordinates.
-
- Technically spoken, there are short code areas in ANIVGA's routines reserved in
- which the right piece of code to transfer/interpret the sprite's data become
- copied, when not already there. For optimal performance it is wise to group the
- entries in SpriteN[] such that adjacent sprite entries share the same display
- method.
-
- See also : convex, concave
-
-
- DUMP_SPR - utility
- ──────────────────
-
- (This is surely a tool for all those hackers among us...)
- If you want to take a closer look at a sprite's data, you don't have to fiddle
- around with DEBUG or the like, just use this sprite dumper: it takes a (binary)
- sprite file (*.COD or *.LIB) and disassembles it into readable ASCII-text.
- You can redirect the output to a file or printer, e.g.:
-
- DUMP_SPR mysprite.cod >mysprite.txt
-
- would dump the sprite file "mysprite.cod" to the ASCII-text file "mysprite.txt"
- for further usage.
- Note that DUMP_SPR creates a format which will be understood by assemblers like
- MASM or TASM so that you can reassemble the files to get a binary sprite file
- once again!
-
-
- ERROR - variable
- ────────────────
-
- Function : Holds the code of the last error which occured
-
- Declaration: VAR ERROR:BYTE
-
- Description: If an error occurs while executing one of its routines, ANIVGA
- terminates that routine and sets ERROR accordingly to reflect that
- error.
- You can use GetErrorMessage() anytime to get more information,
- which error occured.
- It is your responsibility to check if such an error occured and
- react in an appropriate way.
- For the possible values and their descriptions returned by
- GetErrorMessage, see there.
-
- Note (!) : - After processing an error, you have to reset the variable back
- to Err_None yourself"
- - In respect of future extensions, you should treat every value
- <> Err_None as an error
- - The most frequented routine Animate() doesn't produce any
- errors, neither do several other procedures. As a basic rule,
- all routines which have to do with file I/O have to be checked.
- - ERROR is initialized with Err_None
-
- See also : GetErrorMessage, InitRoutines
-
-
- FillBackground - procedure
- ──────────────────────────
-
- Function : Fills the background page with the specified color.
-
- Declaration: {$F+} PROCEDURE FillBackground(color:BYTE); {$F-}
-
- Description: The given value is written into the whole graphic page BACKGNDPAGE
- and thus defines the picture before all animations take place to
- have one color.
-
- Note : Use of this routine only makes sense when using background mode
- STATIC!
-
- See also : Background, BACKGNDPAGE, BACKGNDADR, GetBackgroundFromPage,
- LoadBackgroundPage
-
-
- FillPage - procedure
- ────────────────────
-
- Function : Fills a graphic page completely with a given color
-
- Declaration: {$F+} PROCEDURE FillPage(pa,color:Byte); {$F-}
-
- Description: If you want to paint a complete page uniformly with one color,
- then this will be the fastest method to do it: specify the graphic
- page (0,1 or BACKGNDPAGE (=2)) in "pa" and the color to be used in
- "color".
-
- Note : - Although possible, you are strongly discouraged to use this pro-
- cedure in background mode SCROLLING (i.e.: pa=SCROLLPAGE (=3) as
- page number), because the background is treated completely dif-
- ferent!
- - Remember also that changes to one of the drawing pages (0 or 1)
- have to be applied _after_ calling Animate and will be visible
- for exactly one animation cycle, whereas changes to the back-
- ground page remain permanent (and are best done _before_ calling
- Animate, although that's not peremptory).
- - This routine is great to produce "flashing" screens: apply it to
- 1-PAGE (the visible page).
- - Possible ERROR-values returned are Err_InvalidPageNumber
-
- See also : background, How ANIVGA works, LoadPage, LoadBackgroundPage,
- GetBackgroundFromPage
-
-
- FontOrient, FontHeight, FontWidth - type/constants
- ──────────────────────────────────────────────────
-
- Function : Supply some additional data about the internal font
-
- Declaration: TYPE FontOrient=(horizontal,vertical);
- CONST FontHeight=6;
- FontWidth=6;
-
- Description: The internal font used for displaying graphic text (OutTextXY(),
- BackgroundOutTextXY()) can be displayed either horizontally or
- vertically; use of the TYPE FontOrient simplifies that.
- To compute the width/height of a text, the constants FontHeight
- and FontWidth can be used, which specify the size of one letter.
-
- Note : -
-
- See also : OutTextXY, BackgroundOutTextXY
-
-
- GetBackgroundFromPage - procedure
- ─────────────────────────────────
-
- Function : Take over one of the drawing pages as background image
-
- Declaration: {$F+} PROCEDURE GetBackgroundFromPage(pa:Byte); {$F-}
-
- Description: Specify the graphic page (0 or 1) from which the image should be
- "captured" and the routine will copy its contents into the back-
- ground page BACKGNDPAGE (=2) as new background image.
-
- Note : - Use of the routine only makes sense if STATIC is used as
- background mode.
- - Possible ERROR-values returned are Err_InvalidPageNumber
-
- See also : LoadBackgroundPage
-
-
- GetErrorMessage - function
- ──────────────────────────
-
- Function : Returns a description of the last error occured
-
- Declaration: {$F+} FUNCTION GetErrorMessage:STRING; {$F-}
-
- Description: Although you can use the ERROR variable directly to evaluate any
- error and inform the user about it, it is often more comfortable
- to let ANIVGA do that: GetErrorMessage will give you a string
- describing the last error which occured in words.
- The possible string contents and the corresponding ERROR values
- are:
-
- Err_None: 'No Error'
- No error occured during the routine; this is the variable's
- initial value
-
- Err_NotEnoughMemory: 'Not enough memory available on heap'
- The program couldn't load sprites or other data to the heap
-
- Err_FileIO: 'I/O-error with file'
- There was an error reading the file; either the file doesn't
- exist at the path given or it is damaged
-
- Err_InvalidSpriteNumber: 'Invalid sprite number used'
- This error occurs if you try to load a sprite with a sprite
- loadnumber not in the valid range 1..LoadMAX
-
- Err_NoSprite: 'No (or corrupted) sprite file'
- While attempting to interpret the data just read in, ANIVGA
- found the data not to be in the expected format; either because
- you used a wrong data file or it is damaged
-
- Err_InvalidPageNumber: 'Invalid page number used'
- There are four graphic pages, numbered 0..3. Page 0 & 1 are
- used for the animation itself, page 2 ("BACKGNDPAGE") holds the
- static background image and page 3 ("SCROLLPAGE") is reserved
- for the scrollable background information
-
- Err_NoVGA: 'No VGA-card found'
- The animation package needs a VGA (or compatible) graphic card
- but couldn't find one
-
- Err_NoPicture: 'No (or corrupted) picture file'
- The background picture file ANIVGA should load has not the ex-
- pected size/format or a DOS-error occured while attempting to
- access the data
-
- Err_InvalidPercentage: 'Percentage value must be 0..100'
- If you set the colortable for the shadowing effects of sprite
- display mode Display_SHADOW, you must use a percentage value
- giving the remaining brightness of the colors in the shadow
- areas, which must be in the range 0..100%, of course
-
- Err_NoTile: 'No (or corrupted) tile/sprite file'
- There was an error loading the specified sprite file(s) and
- interpreting them as background tiles. Most often this occurs
- because the sprite doesn't meet the requirement to be a multiple
- of 16 points in its x- and y-directions!
-
- Err_InvalidTileNumber: 'Invalid tile number used'
- There may be only 256 background tiles, numbered 0..255
-
- Err_InvalidCoordinates: 'Invalid coordinates used'
- The virtual background coordinates you use must lie in the range
- (BackX1,BackY1)..(BackX2,BackY2), which has been specified with
- SetBackgroundScrollRange()
-
- Err_BackgroundToBig: 'Background too big for tile-buffer'
- ANIVGA's tile buffer can hold no more than MaxTiles (=10000)
- tiles, that is an area of 10000*16*16 pixels². Check the area
- you specified in your SetBackgroundScrollRange()-call!
-
- Err_InvalidMode: 'Only STATIC or SCROLLING allowed here'
- The only background modes ANIVGA knows are STATIC and SCROLLING
-
- Err_InvalidSpriteLoadNumber: 'Invalid spriteload number used'
- spriteLOADNumbers must lie in the range 0..LoadMAX; when you
- get this error, you probably confounded a spriteLOADnumber with
- a spritenumber
-
- (else): 'Unknown error'
- If ERROR has none of the above values, this string will be
- returned; this should never happen, though.
-
- Note : Calling GetErrorMessage won't set back the ERROR variable either;
- you must do that explicitly!
-
- See also : ERROR
-
-
- GetImage - function
- ───────────────────
-
- Function : Makes a copy of the specified screen region
-
- Declaration: {$F+} FUNCTION GetImage(x1,y1,x2,y2:INTEGER;pa:BYTE):POINTER; {$F-}
-
- Description: - This function works much the same as its equivalent in Turbo-
- Pascal: (x1,y1) and (x2,y2) define the upper left and lower right
- corners of the screen part to save, but now these coordinates are
- _virtual coordinates_, the routine reserves the memory needed to
- hold the copy itself and you can specify the graphic page, from
- which the image is to be taken (pa=0,1 or BACKGNDPAGE (=2) ).
- - As result you get a pointer to the start of the saved image,
- which can be used with PutImage().
- - If there is not enough memory available or the specified part of
- the screen lies completely outside the visible screen, NIL is
- returned.
- - Besides that, there are 5 global variables which are set accor-
- dingly:
- was_cut:BOOLEAN = TRUE/FALSE, if the image had to be _partially_
- clipped (if the specified image is totally offscreen,
- was_cut stays at FALSE!)
- left_cut, right_cut, top_cut, bottom_cut:WORD hold the size how
- much had to be clipped off at the boundaries; these
- values are only set when was_cut=TRUE
- (If you wonder about this odd definitions: GetImage was intended
- to work only with the visible screen (that is: with _absolute_
- coordinates): together with its counterpart PutImage(), you can
- copy a part of the screen to another part or page. In that case,
- you do not have to fiddle around with clipping: just issue a
- GetImage() and use PutImage() to paste this block elsewhere.
- But there may be some applications, when you cut out part of
- the screen and think you got the complete graphic figure you
- wanted, although (because of the use of virtual coordinates and
- your figure being partially offscreen) you got only part of it.
- Checking "was_cut" informs you about such a partial clipping.
- If your figure is completely offscreen, that is a special case:
- it depends on your application whether this should be treated
- as being okay or not; if you need special treatment (as with
- partial clipping), you still can check for this with something
- like:
- ...
- image_ptr:=GetImage(x1,y1,x2,y2,1-PAGE); {1-PAGE=visible page!}
- IF ERROR<>Err_None
- THEN ... {probably not enough memory}
- ELSE IF (was_cut) OR (image_ptr=NIL)
- THEN ... {partial or total clipping occured}
- ELSE ... {no clipping at all}
- )
- - possible ERROR-values returned are: Err_NotEnoughMemory and
- Err_InvalidPageNumber
-
- Note : As already mentioned, GetImage() only works on screen regions in
- the _absolute_ coordinate range 0..319, 0..199, but expects
- _virtual_ coordinates!
-
- See also : PutImage, coordinates
-
-
- GetModeByte - function
- ──────────────────────
-
- Function : Returns the actual display method set for a sprite
-
- Declaration: {$F+} FUNCTION GetModeByte(Sp:WORD):BYTE; {$F-}
-
- Description: "Sp" specifies the spriteLOADnumber of the sprite from which the
- user wants to know the display mode. The function will return one
- of the valid modes Display_NORMAL, Display_FAST or Display_SHADOW.
-
- Note : - Again, spriteLOADnumbers are used!
- - If the LOADnumber given doesn't exist (because no sprite has
- been loaded with that number), the routine will return
- Display_UNKNOWN instead.
-
- See also : Display modes, SetModeByte
-
-
- GetPixel - function
- ───────────────────
-
- Function : Reads a pixel's color
-
- Declaration: {$F+} FUNCTION GetPixel(x,y:INTEGER):BYTE; {$F-}
-
- Description: Returns the color value of the specified pixel with the virtual
- coordinates (x,y) on graphic page PAGE. If (x,y) lies offscreen
- (to be precise: the computed absolute coordinates lie offscreen),
- then zero (= black) is returned.
-
- Note : Be aware that PAGE is the invisible page, not the one you are
- looking at!
-
- See also : coordinates, PAGE, PageGetPixel, PutPixel
-
-
- GRAB - utility
- ──────────────
-
- GRAB allows you to "steal" graphics from other applications and convert them
- into sprite files (*.COD) or background images (*.PIC) for use with ANIVGA.
- This program is a terminate-and-stay-resident (TSR) utility that has to be run
- before starting those applications from which you want to capture graphic
- images.
- Pressing the hotkey CTRL-ALT-G will popup a frame which you can move and resize
- to select the part of the graphic sreen you want to save (if you are not in a
- graphic mode, a graphic mode unknown to GRAB or in a "MSDos critical" situation
- you'll here a beep instead). Use the "i/j/k/m", arrow and "8/6/2/4" keys for
- that task. The space bar will toggle between which corner (the upper left or
- lower right one) will be used for resizing the box. Press ESC anytime to escape
- from GRAB back to your application.
- By default, GRAB starts in sprite capture mode: if you press "s"ave, "w"rite or
- just RETURN, GRAB will generate a sprite file (starting with the file name
- GRAB_000.COD and counting up for following sprites). To get a background image,
- toggle into screen capture mode by pressing "t" (a second "t" will switch back
- to sprite capture mode again), select the screen region wanted and press "s",
- "w" or RETURN to get that part of the screen in the file GRAB_000.PIC (or what-
- ever number is actual then).
- Naturally, you can't resize your frame in the screen capture mode: it stays at
- its initial size of 320x200 points.
-
- Note that GRAB doesn't save color palettes, but only the actual color values of
- all the pixels selected. Because ANIVGA uses the standard palette of graphic
- mode $13, it is possible that images captured with GRAB may have different col-
- ors when used in MAKES or ANIVGA, whenever the application from which you cap-
- tured changed the standard palette!
-
- Note also that there is the same restriction for a sprite's size as in MAKES: a
- sprite may be 152x152 points in max.
-
- As a last point, the usage of GRAB is restricted to all the standard graphic
- modes known by the VGA-BIOS plus the "tweaked" 256 color mode used by ANIVGA
- itself. GRAB uses the BIOS-routines to read and write dots (with the exception
- of the tweaked mode of course) which makes it relatively slow (but reliable).
- As a consequence, you can capture from 16 color or monochrome graphic modes,
- too (although it makes little sense to me capturing 16 or 2 color images for
- usage in a 256 color sprite toolkit...)
-
- See also : MAKES
-
-
- GraphTextBackground, GraphTextColor, GraphTextOrientation - variables
- ─────────────────────────────────────────────────────────────────────
-
- Function : Determine how the OutTextXY()-procedures work
-
- Declaration: TYPE FontChar=ARRAY[0..5] OF BYTE;
- Font=ARRAY[0..255] OF Fontchar;
- FontOrient=(horizontal,vertical);
- CONST GraphTextOrientation:FontOrient=horizontal;
- GraphTextColor:BYTE=white;
- GraphTextBackground:BYTE=white;
- FontHeight=6;
- FontWidth=6;
-
- Description: Whenever text is to be written to the graphic screen, ANIVGA
- consults some global variables. GraphTextColor is simply the color
- in which the text should be drawn, GraphTextBackground specifies
- the color for the pixels in between the letters with one special
- value: if GraphTextBackground=GraphTextcolor, then only the pixels
- belonging to the letters will be drawn with all others remaining
- unchanged.
- Finally, GraphTextOrientation tells ANIVGA in which direction the
- text should be written with two values being possible: HORIZONTAL
- (default) for left-to-right text and VERTICAL for top-to-bottom
- style text.
-
- Note : Default color for the text is "white/white" = "white and don't
- change pixel values between letters".
-
- See also : OutTextXY, BackgroundOutTextXY
-
-
- HitDetect - function
- ────────────────────
-
- Function : Checks whether two sprites collide or not
-
- Declaration: {$F+} FUNCTION Hitdetect(s1,s2:INTEGER):BOOLEAN; {$F-}
-
- Description: Call this routine with the sprite numbers of the two sprites to be
- checked for collision; the function will return TRUE/FALSE when
- the sprites collide/do not collide, respectively.
-
- Note (!) : - Collision detection is independent of whether the sprites are
- visible or offscreen: ANIVGA uses the corrdinates of the two
- sprites given (in SpriteX/Y) and internal data to check.
- - For this it is possible to check for collisions _before_ drawing
- an image (with Animate) and thus make necessary sprite updates
- at once!
- - Inactive sprites cannot collide:
- (SpriteN[s1] or SpriteN[s2]=0) -> FALSE
- - A sprite can't collide with itself: (s1=s2 -> FALSE)
-
- See also : Collision-detection
-
-
- InitGraph - procedure
- ─────────────────────
-
- Function : Initialises the VGA card for the use with ANIVGA
-
- Declaration: {$F+} PROCEDURE InitGraph; {$F-}
-
- Description: ANIVGA uses a special graphic mode, which supports 4 graphic pages
- in the resoultion 320x200 pixels and 256 colors. Because this mode
- is not known by the VGA's BIOS, ANIVGA has to reprogram the VGA.
- You should use this command only once to switch into graphic mode.
-
- Note : InitGraph automatically switches to the invisible graphic page
- 1-PAGE.
-
- See also : Screen, CloseRoutines
-
-
- InitRoutines - procedure
- ────────────────────────
-
- Function : Resets all necessary internal variables of ANIVGA to initial values
-
- Declaration: {$F+} PROCEDURE InitRoutines {$F-}
-
- Description: At program start, some variables have to be set and a few system
- checks are necessary.
- Among these are:
- - SpriteN[] and SpriteAd[] become cleared (= set to 0)
- - Page (the actual drwaing page) is set to 0
- - PageAdr is set to the segment address of the drawing page PAGE
- - BackgroundMode is set to STATIC, i.e.: non-scrollable background
- - BackGndAdr is set to the segment address of the background image
- - StartVirtualX/Y are set to (0,0), making the normal screen coor-
- dinates identical to the virtual screen coordinates
- - the old graphic/text mode which was active at program start is
- stored for restoring it at the program end
- - the system is checked if a VGA card is present and the global
- variable ERROR is set accordingly
- - CycleTime is set to 0, which says that there should be no time-
- control mechanism for the animation rate
- - if the machine is not at least an AT, the time mechanism is
- switched off completely
- - COLOR is set to 15 (= white)
-
- The first thing you should do in your programs is to look at the
- ERROR variable: if it was set to something different from Err_None
- (by the implicit, automatical call of InitRoutines) then your pro-
- gram should no proceed further.
-
- Note : - This routine is called automatically at the very beginning of
- every program which uses ANIVGA. For that, there is normally no
- need to call this routine explicitly.
- - Possible ERROR-values returned are: Err_None and Err_NoVGA
- - Note that this is the _only_ routine that definitely sets the
- variable ERROR, either to Err_None or Err_NoVGA. Because it is
- called at the beginning of every program, it is thus assured
- that your application always has a defined value for ERROR!
-
- See also : ERROR
-
-
- Line - procedure
- ────────────────
-
- Function : Draw a line between the two points specified
-
- Declaration: {$F+} PROCEDURE Line(x1,y1,x2,y2:INTEGER; pa:BYTE); {$F-}
-
- Description: Calling this routine will draw a line between the two points
- (x1,y1) and (x2,y2) on graphic page "pa" and in the color COLOR.
- The routine uses virtual coordinates and clips the line down to
- its visible part.
- "pa" must be one of the values 0, 1 or BACKGNDPAGE (=2).
-
- Note : - As with all point-setting procedures of ANIVGA, you have to re-
- member ANIVGA's working scheme: the first thing ANIVGA does when
- Animate becomes executed is to copy the background image to the
- actual drawing page PAGE, erasing everything on that image.
- For this reason, a line drawn on the visible page 1-PAGE will be
- visible exactly one animation cycle.
- - Possible ERROR-values returned are: Err_InvalidPageNumber
-
- See also : PutPixel, BackGroundLine, coordinates
-
-
- LoadBackgroundPage - function
- ─────────────────────────────
-
- Function : Loads a background image from disk
-
- Declaration: {$F+} PROCEDURE LoadBackgroundpage(name:String) {$F-}
-
- Description: This routine loads a bitmap image stored in file "name" into the
- graphic page used for the background image (BACKGNDPAGE).
-
- Note (!) : - This routine must be called *after* the graphic mode has been
- initialized (with InitGraph())!
- - You can create such images either with the WritePage()- and
- WriteBackgroundPage()-routines of ANIVGA or the GRAB-Utility.
- - Calling this routine is equivalent to use the routine LoadPage()
- with BACKGNDPAGE as second argument.
- - Possible ERROR-values returned are: Err_FileIO and Err_NoPicture
-
- See also : Background, LoadPage, FillBackground, GetBackgroundFromPage,
- InitGraph
-
-
- LoadMAX - constant
- ──────────────────
-
- Function : Specifies the maximum number of different sprites
-
- Declaration: CONST LoadMAX=1000;
-
- Description: For each physical sprite, ANIVGA uses an internal pointer to its
- data. There are LoadMAX pointers, thus there may be up to LoadMAX
- different spriteLOADnumbers (= different sprites).
-
- Note : Don't mix this constant up with NMAX!
-
- See also : NMAX, SPRITE, SpriteLOADnumbers, Spritenumbers
-
-
- LoadPage - procedure
- ────────────────────
-
- Function : Loads a graphic page from disk
-
- Declaration: {$F+} PROCEDURE LoadPage(name:STRING; pa:BYTE); {$F-}
-
- Description: "name" is the MSDOS-path to the graphic image to load, pa the
- destination page (0,1 or BACKGNDPAGE (=2)).
-
- Note : - The graphic mode must have been initialized (vià InitGraph)
- already!
- - You can generate disk files of graphic pages with the help of
- the WritePage()-routine or with the GRAB-utility program.
- - Don't use this routine to load an image into the SCROLLPAGE,
- i.e.: in background mode SCROLLING!
- - Possible ERROR-values returned are: Err_InvalidPageNumber,
- Err_FileIO and Err_NoPicture
-
- See also : GRAB, WritePage, background, InitGraph
-
-
- LoadSprite - function
- ─────────────────────
-
- Function : Loads one (or more) sprites into memory
-
- Declaration: {$F+} FUNCTION LoadSprite(name:String; number:WORD):WORD; {$F-}
-
- Description: "name" is the MSDOS-name of the sprite file to load, which can be
- either a single sprite file (*.COD) or a complete sprite library
- (*.LIB): the function will detect automatically, which format is
- used while loading the data.
- "number" is the spriteLOADnumber, the first loaded sprite will be
- assigned to. If the file contains more than one sprite, they will
- get consecutive LOADnumbers.
- The value returned by the function is the numbers of sprites read
- in (i.e.: 0 means "no sprite read", so you should check ERROR in
- that case).
-
- Note : - Unlike LoadTile(), LoadSprite() loads data into conventional
- memory. For that, you don't have to be in graphic mode to load
- data from disk!
- - Possible ERROR-values returned are: Err_FileIO, Err_NoSprite,
- Err_NotEnoughMemory and Err_InvalidSpriteNumber
-
- See also : sprite format, MAKES
-
-
- LoadTile - function
- ───────────────────
-
- Function : Loads one or more tiles from disk
-
- Declaration: {$F+} FUNCTION LoadTile(name:STRING; number:BYTE):WORD; {$F-}
-
- Description: This routine loads the background tile file "name" into the
- graphic memory area reserved for tiles (the SCROLLPAGE).
- The starting number for the first tile of the file is "number",
- if there are more than one tile in the named file, they will be
- loaded too (with increasing numbers).
- The function returns the number of tiles read in.
-
- Note (!) : - This routine must be called *after* the graphic mode has been
- initialized (with InitGraph)!
- What the function actually does is reading in a sprite and con-
- verting it into an internal tile format: if the sprite read in
- doesn't have the proper size of a tile (16x16 pixels), you nor-
- mally will get an appropriate error (Err_NoTile), with one (use-
- ful) exception: if the sprite can be "cut" into tiles (that is,
- its width and height are multiples of 16 pixels each), then
- LoadTile() will do so with the following numbering scheme: from
- left to right and from top to bottom.
- For example, a sprite with (width,height)=(3*16,2*16) points
- would be numbered as: (assuming that "number" = 0)
- ┌────────┬────────┬────────┐
- │ │ │ │
- │ 0 │ 1 │ 2 │
- │ │ │ │
- ├────────┼────────┼────────┤
- │ │ │ │
- │ 3 │ 4 │ 5 │
- │ │ │ │
- └────────┴────────┴────────┘
- Besides, LOADTILE can load a sprite library, too (they will be
- loaded in the sequence in which they appear in the library).
- - Possible ERROR-values returned are: Err_NotEnoughMemory,
- Err_FileIO, Err_NoTile and Err_InvalidTileNumber
-
- See also : Background, LOADSPRITE, TILE
-
-
- MAKES - utility
- ───────────────
-
- The design of sprites is much to tedious to be carried out manually. For this
- reason, there are two utility programs to simplify that task. The first one
- is a resident program named "GRAB" to capture graphics from other applications
- and convert them into sprites, the second is MAKES, a _simple_ spritemaker
- program (don't expect too much).
- To use it, you must have a mouse installed (and a VGA card, of course).
- (Other than ANIVGA itself, the program uses the "normal" 256-color mode $13, so
- a MCGA-adapter should work also)
- There are no parameters or such things, just start it!
- In the upper right region of the screen there is the so called "work area", in
- which you can paint your sprite pixelwise.
- At the bottom of the screen, all possible colors are available. To choose one,
- point at the color wanted and press the mouse button, to which you want this
- color assigned.
- All other options are so simple that there should be no descriptions necessary,
- so that I only give some general infos here:
- Note that sprites are always stored as the smallest rectangle which surrounds
- them and starts at the upper left corner (0,0): if you don't have special
- reasons to do otherwise, your sprites should start in the upper left corner.
- If for example you realize a sprite consisting of one single point at coordi-
- nates (a,b), the smallest surrounding box with (0,0) as upper left corner would
- be
- (0,0) (a,0) of size (a+1)*(b+1) pixels (=bytes)!!!
- ┌──────────┐
- │ │
- │ │
- │ │
- └──────────▀ <─ this is your 1 point
- (0,b) (a,b)
-
- To determine what areas belong to your sprite and which don't, the program
- assumes color 0 to specify no-sprite-areas and all other colors to be part of
- your sprite (roughly spoken).
-
- The best way to design a sprite is to start with a cleared work area and draw
- the sprite in the midst of it. If you think you're done, use the direction
- boxes to align your sprite with the upper left corner. Then click on the
- "boundaries" option ("see transparent?": no) to see the sprite's size and
- extension in the x/y-directions. This is useful to find very dark points with
- color<>0 set accidentally which would extend the sprite size unnecessarily.
- If you are unsure whether you can use display mode "Display_FAST" or not, call
- "boundaries" a second time and select "see transparent?" _yes_ this time: if
- the blinking white parts "spread" out of the parts you think your sprite should
- be made of, then you should use "Display_NORMAL", if all the blinking areas are
- inside your sprite, you can use "Display_FAST".
-
- Note: - The maximal size for your sprites developped this way is 152x152 points
- (that is only because of the restricted size of the work area on your
- screen; ANIVGA itself can handle sprites up to 32000 pixels in each
- axis or 64K max. size)
- - For more complex sprites, it is often easier to use a commercial pain-
- ting program, capture the sprite with GRAB and edit the resulting
- sprite with MAKES
-
- See also: sprite format, GRAB, Display modes
-
-
- MaxTiles - constant
- ───────────────────
-
- Function : Holds the maximum number of tiles to build the background image
-
- Declaration: CONST MaxTiles=10000;
-
- Description: In background mode SCROLLING, you may use up to MaxTiles tiles
- to build your graphic image.
-
- Note : -
-
- See also : Background
-
-
- NextSprite - variables
- ──────────────────────
-
- Function : Holds the "successors" of sprites for sprite cycles
-
- Declaration: VAR NextSprite: ARRAY [0..LoadMAX] OF WORD
-
- Description: To realize a sprite cycle, you must tell ANIVGA which sprites
- should be drawn one after another. It is this information
- NextSprite holds! For example, let us assume that you wanted to
- make the sprite(loadnumber)s 43, 177 and 111 a sprite cycle, i.e.:
- whenever you set a sprite (to be precise: a SpriteN[]-entry) to
- one of these three numbers, ANIVGA should cycle between the three
- sprite-images in the sequence 43->177->111->43->177->111->...
- You would then set NextSprite[43]:=177; NextSprite[177]:=111 and
- NextSprite[111]:=43 (don't forget this final value!) to do so.
-
- Note (!) : - Most often, you will have the situation that some sprite(load)-
- numbers with consecutive numbers should make up a cycle. In that
- case it is more convenient to use the SetSpriteCycle()-procedure
- to do the job for you
- - Again, note that the routine deals with spriteLOADnumbers! That
- is intentionally, because a sprite cycle is related to the
- _physical_ existent sprite data, or simply spoken: if you make
- 5 pictures to form a flickering torch and you are going to use
- 10 torches in your animation then each of them should loop
- through this 5-picture-cycle, shouldn't it?
- - NextSprite[] is initially set "to point to itself", that is:
- NextSprite[i]=i for all possible i's. If you had to break off
- a sprite cycle (though I can't think what this should be good
- for...), you must restore this data, e.g.: if you wanted to
- break the sprite cycle above, you would have to set
- NextSprite[43]:=43; NextSprite[177]:=177; NextSprite[111]:=43;
- - As this is a global variable, ANIVGA can't check whether your
- settings make sense or not; thus, it remains your responsibility
- to use proper values!
-
- See also : SetSpriteCycle, Sprite cycles
-
-
- NMAX - constant
- ───────────────
-
- Function : Determines the maximum of sprites to be active at the same time
- (minus 1)
-
- Declaration: CONST NMAX=499
-
- Description: This constant sets the size of the internal tables - and thus the
- valid sprite numbers: the indices of the tables SpriteX, SpriteY
- and SpriteN must lie in the range 0..NMAX.
- To state it otherwise, there may be up to NMAX+1 sprites creeping
- around your screen at the same time...
-
- Note : Don't confound that constant with LoadMAX
-
- See also : LoadMAX
-
-
- OutTextXY - procedure
- ─────────────────────
-
- Function : Writes a textstring to the graphic screen
-
- Declaration: {$F+} PROCEDURE OutTextXY(x,y:INTEGER; pa:BYTE; s:STRING); {$F-}
-
- Description: ANIVGA has a built-in font, each character consisting of 6x6
- pixels: very ugly, but hey, we want to make animations, not text!
- To write the string "s" to the graphic screen, you must specify
- the upper left starting corner of the text in (x,y):
- (x,y) -> ▄──────────┐ , where (x,y) are virtual coordinates!
- │ │
- │ │
- │ │
- └──────────┘
- The text will be drawn in color GRAPHTEXTCOLOR and with the orien-
- tation GRAPHTEXTORIENTATION ("VERTICAL" or "HORIZONTAL").
- A third global variable, GRAPHTEXTBACKGROUND, specifies the color
- which will be used for the background area "beneath" the text
- letters; if GRAPHTEXTCOLOR=GRAPHTEXTBACKGROUND then the text will
- be drawn like TurboPascal's routine does: only the pixels be-
- longing to the letters will be drawn, all others remain unchanged.
- "pa" specifies the graphic page to be drawn on and must be one of
- the drawing pages (0 or 1) or the BACKGNDPAGE (=2) for background
- mode STATIC.
-
- Note : - Better fonts could have been developped, but they would all
- depend on special assumptions about the text- and/or background
- color(s).
- This font was intented for short and simple text strings and to
- be as small as possible.
- Nevertheless, using a bigger cell (say: 10x10) and several
- colors (for antialiasing effects) can result in very impressive
- fonts - and work, too...
- - Possible ERROR-values returned are: Err_InvalidPageNumber
-
- See also : GraphtextColor, GraphtextOrientation, GraphtextBackground,
- BackgroundOutTextXY
-
-
- PAGE - variable
- ───────────────
-
- Function : Holds the number of the actual drawing page
-
- Declaration: VAR PAGE:WORD
-
- Description: ANIVGA uses a page flipping approach. Basically this means that it
- alternates between using page 0 and page 1 for its display.
- Although this mechanism should be transparent for the user, ANIVGA
- provides you with the page number of the actual drawing page in
- "PAGE". Note that this number specifies always the invisible page:
- when PAGE=0, then the actual _displayed_ page is page 1 and vice
- versa (ANIVGA always works on the invisible page!).
-
- Note (!) : Only _read_ this value, never assign a new value to it!
-
-
- PAGEADR - variable
- ──────────────────
-
- Function : Holds the segment address of the actual drawing page PAGE
-
- Declaration: VAR PAGEADR:WORD
-
- Description: As already mentioned, there are four graphic pages, numbered from
- 0 to 3. The start addresses of these four pages are used by ANIVGA
- and normally the user should not need to reference them, but with
- PAGEADR at least the address of the actual (invisble) graphic page
- PAGE is available in PAGEADR.
-
- Note (!) : Only use this variable to _read_ its value, never change it!
- Although this 16-bit-value represents only the segment part of the
- complete address, it is the whole address: the address is norma-
- lized in such a way that the offset part is always zero.
-
- See also : PAGE
-
-
- PageGetPixel - function
- ───────────────────────
-
- Function : Returns the color value of the specified point
-
- Declaration: {$F+} FUNCTION PageGetPixel(x,y:INTEGER; pa:BYTE):BYTE; {$F-}
-
- Description: If the point at the virtual coordinates (x,y) and graphic page
- "pa" lies on the screen (i.e.: in the range (0,0)..(319,199) in
- absolute coordinates), this routine will return its color, if it
- is offscreen, the function returns zero.
- "pa" should be one of the values 0, 1 or BACKGNDPAGE (=2).
-
- Note : - If you want to read a pixels' color from the _visible_ page, you
- have to remember that it is the opposite of the _actual_ page
- (that is, you have to use "1-PAGE" as page number).
- - Although only values of 0,1 and BACKGNDPAGE (=2) make sense as
- "pa" values, the routine doesn't check that (for improved speed)
- - For that, the routine _doesn't_ return Err_InvalidPagenumber or
- something similiar in ERROR!
-
- See also : Background, Coordinates, GetPixel
-
-
- PagePutPixel - procedure
- ────────────────────────
-
- Function : Plots a point at a specified page
-
- Declaration: {$F+} PROCEDURE PagePutPixel(x,y:INTEGER; color,pa:BYTE); {$F-}
-
- Description: This routine is very similiar to PutPixel(), but it lets you
- specify explicitly on which graphic page the point shall be drawn.
- (x,y) specify the virtual coordinates of the point to be drawn in
- color "color". If this point lies onscreen (i.e.: its absolute
- coordinates are between (0,0)..(319,199)), it will be drawn on the
- specified page "pa", which must have one of the values 0, 1 or
- BACKGNDPAGE (=2). The latter only makes sense if STATIC is used as
- background mode.
-
- Note : - Don't forget that this routine works with virtual coordinates.
- - Note also that the point is _not_ drawn automatically on the
- background page if pa=0 or pa=1, thus it will be visible exactly
- one animation cycle (and be overdrawn by the background image
- then).
- - Because of ANIVGA's working scheme, you probably want to use
- this routine AFTER calling Animate() (else, your point would be
- overdrawn by the background image immediately) if pa=1-PAGE.
- If you want to draw the point at the _visible_ page, remember
- that it is the "opposite" of the _actual_ drawing page, i.e.:
- you have to use "1-PAGE" for "pa".
- - For improved speed, the routine _doesn't_ check the "pa"
- variable to have a valid value, so there will be no report to
- ERROR (Err_InvalidPageNumber or the like) available!
- It remains your responsibility to assure a proper value for pa!
-
- See also : BackgroundPutPixel, PutPixel, coordinates, How ANIVGA works
-
-
- PutImage - procedure
- ────────────────────
-
- Function : Pastes a formerly copied image to the screen
-
- Declaration: {$F+} PROCEDURE PutImage(x,y:INTEGER; p:POINTER; pa:WORD); {$F-}
-
- Description: PutImage() is the counterpart of GetImage(): use GetImage() to
- copy part of the screen and PutImage to paste it somewhere. (x,y)
- is the upper left corner of the destination (in _virtual_ coordi-
- nates), "p" is the pointer given by GetImage() and "pa" is the
- number of the graphic page (0, 1 or BACKGNDPAGE (=2)) of the des-
- tination.
- If p equals NIL, the routine does nothing at all; this is useful
- because you can PutImage() directly on the result of a GetImage()
- call without further checking for clippings.
-
- Note : - Like GetImage(), this routine also works only when the _virtual_
- coordinates translate into _absolute_ coordinates in the range
- of 0..319, 0..199, that is: they must lie on the visible part of
- the screen, everything else is clipped off.
- - Possible ERROR-values returned are: Err_InvaliPageNumber
-
- See also : GetImage, coordinates
-
-
- PutPixel - procedure
- ────────────────────
-
- Function : Plots a point
-
- Declaration: {$F+} PROCEDURE PutPixel(x,y:INTEGER; color:BYTE); {$F-}
-
- Description: (x,y) specify the virtual coordinates of the point to be drawn in
- color "color". If this point lies onscreen (i.e.: its absolute
- coordinates are between (0,0)..(319,199)), it will be drawn on the
- visible page 1-PAGE.
-
- Note : This routine is not the same as TurboPascal's one: it works with
- virtual coordinates! Note also that the point is _not_ drawn on
- the background page, thus it will be visible for exactly one ani-
- mation cycle (and be overdrawn by the background image then).
- Because of ANIVGA's working scheme, you probably want to use this
- routine AFTER calling Animate() (your point will then be visible
- until the next call to Animate()).
-
- See also : BackgroundPutPixel, PagePutPixel, coordinates, How ANIVGA works
-
-
- PutTile - procedute
- ───────────────────
-
- Function : "Pastes" a tile into the background image
-
- Declaration: {$F+} PROCEDURE PutTile(x,y:INTEGER; TileNr:BYTE); {$F-}
-
- Description: After you have defined a background scrolling area, you can use to
- PutTile() to arrange them as wanted to build your background image.
- (x,y) is the virtual coordinate where you want the tile "TileNr"
- to be placed.
- (x,y) will be changed to be a multiple on 16 in each direction
- and must then lie in the range (BackX1,BackY1)..(BackX2,BackY2).
-
- Note : - Of course, this routine only makes sense when you use background
- mode SCROLLING!
- - (x,y) will be drawn to the upper left to fall on the grid.
- - Possible ERROR-values returned are: Err_InvalidCoordinates
-
- See also : background, tile, SetBackgroundScrollRange, coordinate, BackX1,
- BackX2, BackY1, BackY2
-
-
- Screen - procedure
- ──────────────────
-
- Function : Chooses the display page.
-
- Declaration: {$F+} PROCEDURE Screen(pa:BYTE) {$F-}
-
- Description: Call Screen() with a value between 0 and 3 which tells the routine
- to which graphic page it should switch. This is done by repro-
- gramming the VGA start address registers. For a flickerfree dis-
- play, this switching is synchronized to the vertical retrace
- signal.
-
- Note (!) : - You should not use this routine if you are not absolutely sure
- what you are doing! Be aware that ANIVGA relies on the fact that
- the actual drawing page is PAGE and its segment address is in
- PAGEADR while the visible page is 1-PAGE!
- - Although it makes little sense to apply this routine to graphic
- pages other than 0 or 1, it is possible to set "pa" to 2 (=BACK-
- GNDPAGE) or 3 (=SCROLLPAGE).
-
- See also : PAGE, PAGEADR, InitGraph
-
-
- ScrollPage - constant
- ─────────────────────
-
- Function : Holds the page number of the backround page
-
- Declaration: CONST SCROLLPAGE=3;
-
- Description: When using background mode SCROLLING, BackGndPage specifies the
- page number of the tile buffer used to build up the background
- image for animations.
-
- Note (!) : Use of this constant only makes sense when using background mode
- SCROLLING!
-
- See also : BackGndPage, Background
-
-
- SetBackgroundMode - procedure
- ─────────────────────────────
-
- Function : Chooses one of the possible background modes of ANIVGA
-
- Declaration: {$F+} PROCEDURE SetBackgroundMode(mode:BYTE); {$F-}
-
- Description: ANIVGA has two possible ways of handling background you can choose
- of: "STATIC" or "SCROLLING" backgrounds with several advantages
- and disadvantages, each (see background). Specify the mode you
- want to use in the "mode" variable.
-
- Note : - Default value set by ANIVGA is STATIC.
- - Possible ERROR-values returned are: Err_InvalidMode
-
- See also : background
-
-
- SetBackgroundScrollRange - procedure
- ────────────────────────────────────
-
- Function : Specifies the scrollable background area in mode SCROLLING
-
- Declaration: {$F+} PROCEDURE SetBackgroundScrollRange(x1,y1,x2,y2:INTEGER) {$F-}
-
- Description: (x1,y1) is the upper left corner of the background scroll area,
- (x2,y2) the lower right corner (all virtual coordinates).
- ANIVGA will round the points given to fit on a grid with mesh 16,
- that is, x1,y1,x2,y2 will be changed to be all multiples of 16.
- These new values will be stored in the (global) variables BackX1,
- BackY1, BackX2, BackY2 for further use.
- Besides that, XTiles and YTiles will hold the width and height of
- the choosen background area in tiles.
-
- Note : - You can read the Back??-variables for your information, but
- don't change them!
- - Of course, this routine only makes sense when you are going to
- use SCROLLING as background mode.
- - The upper left corner (x1,y1) will be drawn to the upper left,
- the lower right corner (x2,y2) to the lower right to fall on the
- grid.
- - Don't forget that the tile memory is limited; you can't select
- an area bigger than MaxTiles (=10000) tiles, that is more than
- 2560000 pixels².
- - Possible ERROR-values returned are: Err_InvalidCoordinates and
- Err_BackgroundToBig
-
- See also : background, tiles, PutTile
-
-
- SetCycleTime - procedure
- ────────────────────────
-
- Function : Defines the maximum animation speed
-
- Declaration: {$F+} PROCEDURE SetCycleTime(milliseconds:WORD); {$F-}
-
- Description: There are lots of PC-compatible machines with a broad range of
- clock rates, wait states and different speeds of their graphic
- cards. With this routine you can set the time an animation cycle
- has to last at least: at the very end of Animate, the routine
- checks whether at least "milliseconds" milliseconds have been past
- since the last call to this routine and waits if necessary.
- If you give 0 milliseconds as an argument or your machine is not
- (at least) an AT class machine, there will be no such time control
- mechanism and the animation will always take part at the maximal
- speed on the specific machine (this is also the default value).
-
- For example: "SetCycleTime(100);" would restrict the animation
- rate even on the fastest 80586 machines to at most 1sec/100msec
- = ten frames per second.
-
- Note (!) : - Because there is no such high precision timer on PC/XT computers
- as required, SetCycleTime() is ignored on these machines.
- Anyway, this should be not to hard because these computers are
- normally that slow that they would not have been slowed down
- either.
- - The accuracy of this timing mechanism is better than 1 milli-
- second.
-
-
- SetModeByte - procedure
- ───────────────────────
-
- Function : Specifies the way a sprite will be displayed
-
- Declaration: {$F+} PROCEDURE SetModeByte(Sp:WORD; M:BYTE); {$F-}
-
- Description: This routine assigns one of the possible display methods "M"
- (Display_NORMAL, Display_FAST, Display_SHADOW) to the specified
- spriteLOADnumber "Sp".
-
- Note : - Because this kind of information is stored directly inside the
- sprite data, the sprite must have been loaded already for this
- action to work.
- - For the same reason, this routine works on spriteLOADnumbers,
- not sprite numbers (>gee, again!<): a display method set for one
- spriteLOADnumber will affect all sprites with that LOADnumber!
- Most often, that is okay (e.g.: if you use the sprite of a foot-
- ball player ten times, it is quite normal to use the same dis-
- play mode for all ten players!), if you really must use a sprite
- with two different display methods at the same time, you can use
- the following trick: load the sprite's data a second time into
- memory, using a different spriteLOADnumber. For this second
- copy, you can use another display mode.
- - Possible ERROR-values returned are: Err_InvalidSpriteNumber and
- Err_InvalidMode
-
- See also : SpriteLoadNumber, SpriteNumber, Display methods, GetModeByte
-
-
- SetShadowTab - procedure
- ────────────────────────
-
- Function : Set the amount of shadowing in display mode "Display_SHADOW"
-
- Declaration: {$F+} PROCEDURE SetShadowTab(brightness:BYTE); {$F-}
-
- Description: Whenever a sprite is drawn in "Display_SHADOW" mode, ANIVGA must
- know how much darker these shadow areas should be, compared with
- the brightness of the original (not-shadowed) colors.
- These data is held in the table ShadowTab and is set to 70% of
- the colors original brightness. However, you can use this routine
- to provide more or less darker shadow areas: "brightness" is the
- percentage of the colors original brightness which shall remain,
- e.g.: brightness=0 would mean every shadow is completely black,
- brightness=100 is the original color as shadow (not darkened at
- all), brightness=40 will darken every color by 100-40=60%, etc.
-
- Note (!) : - This routine takes quite a long time (app. 4s on an 8MHz AT).
- - The argument will be only approximated: the algorithm computes
- the 256 color values needed precisely and matches them as close
- as possible to the 256 default colors of graphic mode $13.
- Note that the palette registers of the VGA card *won't* be
- changed at all! ANIVGA still works with the standard VGA palette
- of the BIOS; what it does is solely creating a color look-up-
- table!
- - Possible ERROR-values returned are: Err_InvalidPercentage
-
- See also : ShadowTab, Display modes, SetModeByte
-
-
- SetSpriteCycle - procedure
- ──────────────────────────
-
- Function : Links spriteLOADnumbers together to form a sprite cycle
-
- Declaration: {$F+} PROCEDURE SetSpriteCycle(nr,len:WORD); {$F-}
-
- Description: "nr" is the first spriteLOADnumber to be included in the sprite
- cycle and "len" entries (i.e.: from "nr" to "nr+len-1") should be
- tied together.
- The routine will then set the according NextSprite[] entries to
- build this cycle: nr -> nr+1 -> nr+2 -> ... -> nr+len-1 -> nr
-
- Note : - The routine uses spriteLOADnumbers, _not_ sprite numbers!
- - If you want to link sprite(loadnumber)s which do not have conse-
- cutive (load)numbers, you must do that by setting NextSprite[]
- accordingly.
-
- See also : Sprite cycles, NextSprite
-
-
- ShadowTab - "procedure"
- ───────────────────────
-
- Function : Table for translating sprite colors into others
-
- Declaration: {$F+} PROCEDURE ShadowTab; {$F-}
-
- Description: If the display mode "Display_SHADOW" is set for a physical sprite,
- its colors will depend not on the values stored in the sprite it-
- self, but on the values found on the screen at the place where the
- sprite shall be drawn: every pixel of the sprite will become dar-
- kened by substituting its corresponding color against the color
- stored in this color table.
- At startup, this table is set to make shadows be approximately 70%
- the brightness of the original colors, but you can adjust this
- with the routine SetShadowTab() if this default is not suitable
- for your application.
- You can even supply a completely different color table (for
- special effects?).
- To do so, define an array "[0..255] of byte" (you can use the pre-
- defined TYPE ColorTable for this), containing for each color of
- the standard palette its substitute (e.g. setting array element
- [8]:=13 would mean: "replace every pixel in the shadow area with
- color 8 against a pixel with color 13") and overwrite the original
- color table by issuing the command "MOVE(my_array,@ShadowTab^,256)"
-
- Note : - Although this table is declared as a procedure, it really is
- data, not code; so don't call it!
- - There can be only _one_ color table and it is only active in
- display mode "Display_SHADOW".
-
- See also : SetShadowTab, Display modes, SetModeByte
-
-
- SPRITE, Spritenumbers, Spriteloadnumbers - information
- ──────────────────────────────────────────────────────
-
- A sprite is the basic data element used in ANIVGA. Technically spoken, it is
- nothing more then a two-dimensional array of bytes which becomes copied to the
- screen positions needed, but it is far more comprehensive to think about it as
- a photograph of a figure which can be pasted to the screen whereever you want.
- To distinguish between different sprites, we use natural numbers, but whenever
- we talk about "sprites", we are somehow inaccurate:
- You should notice that there are two kinds of "sprite numbers" which should
- not be mixed up: one is a spriteLOAD number and represents a handle to the
- (physical) sprite data, while the other (normally termed "sprite number") is
- a logical number to address the sprite data.
- Yet, most often it is clear from the context, which meaning is intended:
- For a simple example: if you are going to animate a soccer team, you would
- need 11 sprites for the player - but they all have the same shape. This means,
- you only have to load one sprite (-> you need 1 spriteLOAD number), but need
- 11 copies of that to move around the screen (-> you need 11 sprite numbers).
- (See section "How ANIVGA works" for more about that)
- You can design sprites with the help of the spritemaker-tool MAKES, by using
- GRAB to capture and convert graphic screens from other graphic applications
- or write your own tools for that (it's really not that difficult you think
- now it would be...).
-
- See also : sprite format, How ANIVGA works
-
-
- SPRITE CYCLES - information
- ───────────────────────────
-
- Often, you don't want to have a single picture as sprite, but a sequence of
- them which should loop forever. For example, let's assume that you use a torch
- as an animation object in your application and you want it to have a flickering
- flame.
- You would start to draw 5 (say) pictures, which -repeatedly displayed one after
- another- would make the impression of your flickering torch. But within your
- application, you still want to handle these five different images as one single
- object - namely the sprite "torch".
- To do so, you can use a capability of ANIVGA, called a "sprite cycle": load the
- five images as (physical) sprites and tie their loadnumbers together to form
- that sequence!
- The easiest way to do that would be to load the images with consecutive numbers
- and use the SetSpriteCycle() procedure to form the sprite cycle (see there).
- Note that we are talking about linking spriteLOADnumbers here: when you have
- built such a cycle for your torch and you want to use 10 torches in your
- program, you surely want that each of them behaves the same, that is: they all
- should show a flickering flame by using that sprite cycle.
- For this reason, ANIVGA uses spriteLOADnumbers, so that every instantiation of
- a spriteLOADnumber (i.e.: a SpriteN[]-entry) belonging to a cycle will lead to
- a sprite cycle for this sprite!
- A small detail at last: if you defined a sprite cycle to be a->b->c->a->...,
- and initialized a SpriteN[]-entry to "a", then the first sprite displayed at
- the screen will be "b" instead of "a" - why?
- Well, ANIVGA handles sprite cycles in the Animate() routine and thus has two
- possibilities to update the SpriteN[]-table (by issuing a "SpriteN[] :=
- NextSprite[SpriteN[]]" command): _before_ drawing the sprites or _afterwards_.
- But when it does _after_ drawing the sprites, the sprites displayed on your
- screen (=the old SpriteN[] values before doing the above command) are inconsis-
- tent to the according numbers actually held in the SpriteN[]-table!
- This could lead to problems (e.g.: when you do a HitDetect() after calling
- Animate()). Although this could be circumvented by a special grouping of sub-
- routine calls, it is far more convenient to update the SpriteN[]-table _before_
- drawing the sprites.
- The only drawback with this method is the one stated in the beginning: not the
- SpriteN[]-entry supplied by you will be drawn, but its "successor"
- NextSprite[SpriteN[]]!
- However, most often that won't be that bad and *if* it would, you still could
- compensate for it by using the sprite's predecessor (in the above example, you
- would use "c", as it is the predecessor of "a", to display "a").
-
-
- SPRITE FORMAT - information
- ───────────────────────────
-
- As already said, a sprite is nothing more then a two-dimensional array of bytes
- which becomes copied to the screen positions needed.
- For quick animations, the data should be stored in a format which causes few
- and simple transformation steps when accessing the data, but it is hard to
- keep up with that principle, because the graphic mode used is "planed".
- This means that points are _not_ stored sequentially into the graphics memory,
- but in a rather strange way: every 4 points use the same address, but lie in
- different "bitplanes". To cut it short: clipping and drawing sprites is hell
- therefore (and surely one reason why there are so less tools for this mode)
- and ANIVGA uses a very special format to store a sprite (= *.COD-files):
-
- 0..1 DW offset to Plane_0_Data (points with x-coord. MOD 4=0)
- 2..3 DW offset to Plane_1_Data (points with x-coord. MOD 4=1)
- 4..5 DW offset to Plane_2_Data (points with x-coord. MOD 4=2)
- 6..7 DW offset to Plane_3_Data (points with x-coord. MOD 4=3)
- 8..9 DW sprite width (DIV 4), rounded up if not dividable by 4
- 10..11 DW sprite height in lines
- 12..15 DB 1,2,4,8 ; constants (translate-table)
- 16..17 DW SpriteLength ; length of this sprite file
- 18..37 DW 10 dup(?) ; reserved area for future use
- 38..39 DB 'K','R' ; code for "this is a sprite file"
- 40 DB 1 ; version
- 41 DB 0 ; default display mode (0=Display_NORMAL)
- 42..43 DW offset pointer to left boundary table
- 44..45 DW offset pointer to right boundary table
- 46..47 DW offset pointer to top boundary table
- 48..49 DW offset pointer to bottom boundary table
- 50..SpriteLength-1: boundary- and plane data tables
-
- (If you should wonder why all pointers are only 16 bit long: the maximal size
- of one sprite is 64k, so offset pointers are sufficient.
- Another trick is that ANIVGA loads sprites at segment boundaries; for that,
- you don't have to distinguish between "relative offsets" and "offset poin-
- ters": if normalized segment addresses (=offset part is ε [0..15]) are used to
- address sprites, the offset part is always 0, so the two terms are identical!)
-
- The Plane_?_Data tables consist of the points of the sprite (1 pixel = 1 byte);
- if the sprite width is 12 pixels (say), then each table would hold 12/4=3 bytes
- for each of the sprite's rows:
- Plane_0_Data = color of pixels 0,4,8 of 1. sprite row
- color of pixels 0,4,8 of 2. sprite row
- ...
- Plane_1_Data = ditto, for pixels 1,5,9
- Plane_2_Data = ditto, for pixels 2,6,10
- Plane_3_Data = ditto, for pixels 3,7,11
-
- The boundary tables hold the outermost positions of the sprite:
- The left/top/right/bottom boundary table holds the leftmost/topmost/rightmost/
- bottomost pixel of each row/column/row/column (or 16000/16000/-16000/-16000 if
- none exists), respectively:
- left boundary table = leftmost pixel coordinate of 1. sprite row (or 16000)
- leftmost pixel coordinate of 2. sprite row (or 16000)
- ...
- Note that each entry in the boundary tables consists of a signed integer!
-
- Note also that sprites are always stored as the smallest, the figure including
- box (rounded up in the x-direction to the next multiple of 4), but that the
- values of the "superfluous points" stored in the plane tables doesn't matter at
- all (no difference which display mode is used for the sprite!), because ANIVGA
- uses only the bytes of the areas which belong to the _real_ sprite-figure
- (ANIVGA determines this parts by assuming the sprite to be "horizontal convex"
- and uses the boundary tables to compute them).
- (Don't worry if you do not understand these technical details now -- hopefully,
- you won't need them at all).
-
- See also : MAKES, Display modes, convex, sprite library
-
-
- SPRITE LIBRARY - information
- ────────────────────────────
-
- Sprite files can be combined to sprite libraries. The main advantage of this is
- that you can reduce the number of files needed for your programs dramatically:
- A normal program will use approximately 20..40 different sprites, so that you
- would have 20..40 files only for your sprites!
- But ANIVGA's routine to load sprites "loadSprite()" is flexible enough to dis-
- tinguish whether the file to be loaded contains one or more sprites and loads
- them all.
- To construct such a "sprite library" (suggested filename extension: .LIB), you
- just use MSDos' COPY-command with the binary option "/B"; for example:
-
- COPY /B sprite1.cod+d:\sprites\sprite2.cod+testspr.cod A:\mylib.lib
-
- would concatenate the three sprites "sprite1.cod", "d:\sprites\sprite2.cod" and
- "testspr.cod" and build the sprite library "A:\mylib.lib".
- You can reverse this process with the UNLIB-utility.
-
- See also : UNLIB, sprite format, loadSprite
-
-
- SpriteAd - variable
- ───────────────────
-
- Function : Store the pointers to the sprites' data
-
- Declaration: VAR SPRITEAD:ARRAY[0..LoadMAX] OF WORD;
-
- Description: Whenever you load a (physical) sprite with LOADnumber xxx, ANIVGA
- stores the sprite's data somewhere in RAM and maintains a pointer
- which points to the beginning of this data as a handle to access
- the data: this handle is stored in SpriteAd[xxx] and reflects the
- segment part of the starting address of the data.
-
- Note : Don't change that data directly unless you are absolutel sure what
- you are doing!
-
- See also : LoadSprite, SPRITE, Sprite Format
-
-
- SPRITEN, SPRITEX, SPRITEY - tables
- ──────────────────────────────────
-
- Function : Hold the values of all sprites to be drawn in the next animation
- cycle.
-
- Declaration: VAR SpriteN:ARRAY[0..NMAX] of Integer (SpriteX/Y dto.)
-
- Description: ANIVGA is based on tables: in SpriteN[] you must declare, which
- sprites shall be drawn in the next animation step. To do that,
- store the spriteLOAD number of the sprites into the SpriteN[]-
- entries; a zero indicates that the according sprite is inactive
- and should not be displayed.
- For every active sprite (SpriteN[i]<>0), a pair of virtual coor-
- dinates in the range -16000..+16000 must be specified in the
- SpriteX[i] and SpriteY[i] entries to determine the sprites' po-
- sition on the (virtual) screen.
- These coordinates will be transformed internally into real coor-
- dinates to decide whether the sprite is onscreen and has to be
- displayed or not.
-
- Note : If you have less sprites than are allowed by the system (that is:
- less than NMAX+1), your decision what table entries you use are
- arbitrary; if for example you have only two sprites, it won't
- matter, if you use SpriteN[0] for the first one and SpriteN[1]
- for the other or vice versa, or SpriteN[123] and SpriteN[310] or
- whatever valid indices you can think of - except in one point:
- the sprites are drawn in reverse order, that means SpriteN[NMAX]
- is drawn first, then SpriteN[NMAX-1] ... SpriteN[0].
- For that, if two (or more) sprites overlap each other, the one
- with the smallest index is drawn topmost and covers the other(s).
-
- For performance reasons you should observe another rule: if you
- use different display methods for different sprites then try to
- group your sprites in such a way, that sprites with the same dis-
- play method have continous indices. As an example: if the sprites
- with (load)number 1 use one method and the ones with number 2
- another, then the sequence SpriteN[]=(...2,2,2,2,2,...,1,1,1...)
- would be better than (...2,2,1,2,...,1,2,...,1,2,...).
- This is due to the fact that whenever ANIVGA has to draw a sprite
- with a display method other than the active one, it must inter-
- nally switch from one method to the other which costs some time.
-
- See also : SetModeByte
-
-
- StartVirtualX, StartVirtualY - variables
- ────────────────────────────────────────
-
- Function : Specify the upper left corner of the visible world
-
- Declaration: CONST StartVirtualX:INTEGER=0;
- StartVirtualY:INTEGER=0;
-
- Description: When working with virtual coordinates, your screen displays only a
- very small window (320x200 points) of this "virtual screen"
- (32000x32000 points). To tell ANIVGA which part of this virtual
- screen is to be displayed, you specify the upper left corner of
- the visible part in (StartVirtualX,StartVirtualY).
- For example, setting (StartVirtualX,StartVirtualY) to (100,1000)
- would define that the part of the virtual screen having x-coordi-
- nates ε [100..100+XMAX] and y-coordinates ε [1000..1000+YMAX] to
- be displayed.
-
- Note : Setting these variables doesn't affect the HitDetect-function: if
- two sprites collide outside the visible area, it will be detected,
- still.
-
- See also : coordinates
-
-
- Table - TYPE
- ────────────
-
- Function : Supply a data type for the animation variables
-
- Declaration: TYPE Table=ARRAY[0..NMAX] OF INTEGER;
-
- Description: A lot of variables in ANIVGA have to be of type "one entry for
- each sprite" and "Table" is the appropriate form for that.
-
- Note : -
-
- See also : SpriteX, SpriteY, SpriteN
-
-
- Tile - information
- ──────────────────
-
- "Tiles" are graphic images, 16 pixels wide and high. They are used to define a
- scrollable background image when you use SCROLLING as background mode.
- Due to memory limitations, it is impossible to hold a complete background image
- in memory (because virtual coordinates range 32000 pixels in x/y-directions,
- one would need app. 977 MB (!) RAM for that).
- Instead, you may define up to 256 different tiles and then combine them to form
- the graphic background, which may consist of up to MaxTiles (=10000) tiles
- (using the 256 different tiles).
- (A simple example for that can be found by "Background").
- ANIVGA stores tiles in a slightly different format then sprites internally, but
- you don't have to bother your head about that: on disk, tiles have the same
- format as sprites, so you can use all the utility programs to create/edit
- sprites also to create/edit tiles! The only restriction you have to care about
- is, that a tile has the definite size of 16 pixels in each direction (but see
- the LoadTile()-function for some simplifications about even that).
-
- See also : Background, LoadTile
-
-
- UNLIB - utility
- ───────────────
-
- Sometimes, you will want to reverse the process of building a sprite library,
- that is: you want to split a sprite library into the sprite files of which it
- consists.
- To do that, call UNLIB with the name of the sprite library to split. UNLIB will
- then create the files UNLIB000.COD, UNLIB001.COD, UNLIB002.COD,... which re-
- present the sprite files wanted.
- Note here that UNLIB cannot restore the original filenames you used (there is
- no such entry in a sprite's header). For that, it is a good idea to write down
- the names and sequence of the sprite files used in building a sprite library.
- (If you didn't, you still can load every extracted sprite with MAKES, look at
- it and give it the right name then)
-
- See also : sprite library, MAKES, sprite format
-
-
- VIRTUAL COORDINATES - information
- ─────────────────────────────────
-
- See : coordinates
-
-
- WriteBackgroundPage - procedure
- ───────────────────────────────
-
- Function : Saves the background image to disk
-
- Declaration: {$F+} PROCEDURE WriteBackgroundPage(name:STRING); {$F-}
-
- Description: This is merely a shortcut of the WritePage()-procedure (see
- there), i.e. WritePage(name; BACKGNDPAGE) would do an equivalent
- job.
-
- Note : Possible ERROR-values returned are Err_FileIO
-
- See also : WritePage
-
-
- WritePage - procedure
- ─────────────────────
-
- Function : Saves a graphic page to disk
-
- Declaration: {$F+} PROCEDURE WritePage(name:STRING; pa:BYTE); {$F-}
-
- Description: To save an image of one of the drawing pages (0 or 1) or the back-
- groundpage BACKGNDPAGE (=2), specify the approriate page number in
- "pa" and a valid MSDOS-path/name where to store the data in
- "name".
-
- Note : - Make sure that your disk has enough space to hold the data: one
- page is stored as 64003 bytes!
- - You can't use this procedure for saving the background page "pa"
- =SCROLLPAGE in background mode SCROLLING!
- - Possible ERROR-values returned are: Err_InvalidPageNumber and
- Err_FileIO
-
- See also : WriteBackgroundPage, LoadPage
-
-
- XMAX - constant
- ───────────────
-
- Function : Specifies the maximal absolute x-coordinate
-
- Declaration: CONST XMAX=319
-
- Description: XMAX is the biggest _absolute_ coordinate in the x-direction which
- can be used: all x-coordinates must lie in the range 0..XMAX.
-
- Note : Probably, you will never use this constant at all, because nearly
- everything in ANIVGA's user interface works with _virtual_ coordi-
- nates, but who knows...
-
- See also : YMAX, coordinates
-
-
- XTiles - variable
- ─────────────────
-
- Function : Holds the width of the scrollable background image in tiles
-
- Declaration: VAR XTiles:INTEGER;
-
- Description: When using background mode SCROLLING, you have to specify the size
- of your scrolling background area (with the SetBackgroundScroll-
- Range()-procedure). ANIVGA adjusts these values slightly and
- computes the size of the resulting background image in tiles.
- The width of this area (in tiles) is then stored in XTiles.
-
- Notes : Don't change this variable directly!
-
- See also : YTiles, Background, SetBackgroundScrollRange
-
-
- YMAX - constant
- ───────────────
-
- Function : Specifies the maximal absolute y-coordinate
-
- Declaration: CONST YMAX=199
-
- Description: YMAX is the biggest _absolute_ y-coordinate which may be used,
- that is, every y-coordinate must lie in the range 0..YMAX.
-
- Note : Probably, you will never use this constant at all, because nearly
- everything in ANIVGA's user interface works with _virtual_ coordi-
- nates, but who knows...
-
- See also : XMAX, coordinates
-
-
- YTiles - variable
- ─────────────────
-
- Function : Holds the height of the scrollable background image in tiles
-
- Declaration: VAR YTiles:INTEGER;
-
- Description: When using background mode SCROLLING, you have to specify the size
- of your scrolling background area (with the SetBackgroundScroll-
- Range()-procedure). ANIVGA adjusts these values slightly and
- computes the size of the resulting background image in tiles.
- The heigh of this area (in tiles) is then stored in YTiles.
-
- Notes : Don't change this variable directly!
-
- See also : XTiles, Background, SetBackgroundScrollRange
-