VGA programming and ModeX

TBA - To Be Added
[Frequently Asked Questions about VGA]
Q1.1    How do I program in mode xxx on my XXX?
Q1.2    What is modeX?
Q1.3    How do I program the VGA?
[Frequently Asked Questions about Sound Cards]
Q2.1    How do I program my XXX?

--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER     IBM FAQ        VGA
--------------------------------------------------------------------------------
Q1.1    How do I program in mode xxx on my XXX?

    Perhaps the most frustrating thing that has ever been done is
    the plithera of extended VGA modes.  Unfortunately on the VGA
    is general enough for this FAQ to cover.  There is much too
		much to know about other mode other than those supported by
    VGA, that can be covered in such a SMALL amount of FAQ room.

Q1.2    What is modeX?

     The VGA card has 256K of memory built into it.  It uses the 64K 
     segment located at segment A000 for a "frame" into the 256K of
     memory.  In other words, when you write to A000, the VGA card 
     wakes up, grabs the data, and puts it somewhere in its 256K of
     memory. 

     In VGA's mode 13H, the pixels are stored in planes like this:
     (x,y) = 1 byte of pixel data for location x,y

                          ---------------------
      Plane 3           | 3,0 | 7,0 | 11,0 | ...
                       ---------------------
      Plane 2        | 2,0 | 6,0 | 10,0 | ...
									 --------------------
      Plane 1    | 1,0 | 5,0 | 9,0 | ...
                --------------------
      Plane 0   | 0,0 | 4,0 | 8,0 | ...
                | 0,1 | 4,1 | 8,1 | ...
        .
        .
     
      In mode 13h, you access a pixel by using a 16-bit offset into
      the video frame.  The VGA card takes the lower 2 bits and uses this
      to select the plane that the byte will go to.  The other 14 bits
      are used as the offset into the plane. This is what is called
      "chain 4" mode.

      ModeX is identical to mode 13h, but "chain 4" mode is turned
      off so that now when you access the VGA card with a 16-bit offset
      into the video frame, it uses the "Map Mask" register value to 
      determine what plane to write to and then uses your 16-bit offset
			to offset into the plane.  In other words, you now have an 18-bit
      address by using a 16-bit pointer and a 2-bit out.  This allows you
      to then access all 256K of the VGA memory, at the expense of having
      to do an OUT for every pixel.

      But remember, internally, the data is stored *IDENTICALLY*.

      You just have to choose between a "slow" 18-bit pointer or
      a "fast" 16-bit pointer to decide whether to use ModeX or not.

Q1.3    How do I program the VGA?

    Well the following should help, there are several books on
		programing the VGA chipset.  If the following appears
    complicated, sorry such is the nature of VGA!

Documentation over the I/O registers for standard VGA-cards

Documentated by Shaggy of The Yellow One.

Email: D91-SJD@TEKN.HJ.SE

Feel free to spread this to who ever wants it.....
------------------------------------------------------------
Port-Index:  -               Port: Write/03c2h Read/03cch
usage:       d7   Vertical sync polarity
             d6   Horizontal sunc polarity
             d5   Odd /even page
             d4   Disable video
             d3   Clock select 1
             d2   Clock select 0
						 d1   Enable/Disable display RAM
             d0   I/O address select
Description: Sync polarity: Bits are set as below for VGA displays
             that use sync polarity to determine screen resolution.
             Many newer multiple frequency displays are insensitive
						 to sync polarity

             d7 d6      Resolution
             0  0       Invalid
             0  1       400 lines
             1  0       350 lines
             1  1       480 lines

             I/o address select: When set to zero, selects the
             monochrome I/O address space (3bx). When set to one,
             it selects the color I/O address space (3dx)

------------------------------------------------------------
Port-Index: -                Port: 03c2h ; read only
usage:      d7    Vertical Retrace Interrupt pendling
            d6    Feature connector bit 1
            d5    Feature connector bit 0
            d4    Switch sense
						d0-d3 Unused

Description: d7 uses IRQ2

------------------------------------------------------------
Port-Index: -                Port: 03bah,03dah ; read only
usage:      d3  Vertical retrace
            d0  Horizontal retrace

------------------------------------------------------------
Port-Index: -                Port: 03c3h,46e8h
usage:      d7-d1  Reserved
            d0     VGA enable/disable (03c3h only)

Description: Disables access to display memmory and the other
             VGA's ports

------------------------------------------------------------
Port-Index: 00h              Port: 03d4h, 03b4h
usage:      Horizontal total
Description: Total number of characters in horizontal scan minus
             five ( including blanked and border characters)

------------------------------------------------------------
Port-Index: 01h              Port: 03d4h, 03b4h
usage:      Horizontal display enable
Description: Total number of characters displayed in horizontal
             scan minus one.
------------------------------------------------------------
Port-Index: 02h              Port: 03d4h, 03b4h
usage:      Start horizontal blanking
Description: Character at which blanking starts

------------------------------------------------------------
Port-Index: 03h              Port: 03d4h, 03b4h
usage:      End horizontal blanking
						d7    Test
            d6    Skew control
            d5    Skew control
            d0-d4 End blanking
Description: End blanking: is five LSB bits of six-bit value,
             which define the character at which blanking stops.
             The MSB bit of this value is in register index 5.

------------------------------------------------------------
Port-Index: 04h              Port: 03d4h, 03b4h
usage:      Start horizontal retrace
Description: Character at which horizontal retrace starts

------------------------------------------------------------
Port-Index: 05h              Port: 03d4h, 03b4h
usage:      End horizontal retrace
            d7    End horizontal blanking bit 5
            d6    Horizontal retrace delay
						d5    Horizontal retrace delay
            d0-d4 End horizontal retrace
Description: End horizontal retrace: defines the character at
             which horizontal retrace ends

------------------------------------------------------------
Port-Index: 06h              Port: 03d4h, 03b4h
usage:      Vertical total
Description: Total number of horizontal scan lines minus two
             (including blanked and border characters). MSB bits
             of this value are in register index 7

------------------------------------------------------------
Port-Index: 07h              Port: 03d4h, 03b4h
usage:      Overflow register
            d7  Vertical retrace start (bit 9)
            d6  Vertical display enable end (bit 9)
            d5  Vertical total (bit 9)
						d4  Line compare (bit 8)
            d3  Start vertical blank (bit 8)
            d2  Vertical retrace start (bit 8)
            d1  Vertical display enable end (bit 8)
            d0  Vertical total (bit 8)
------------------------------------------------------------
Port-Index: 08h              Port: 03d4h, 03b4h
usage:      Preset row scan
            d7    Unused
            d6    Byte panning control
            d5    Byte panning control
            d0-d4 Preset row scan
Description: Byte panning control: is used to control byte
						 panning. This register together with attribute
             controller register 13h allows for up to 31 pixels of
             panning in double word modes
             Preset row scan: Which character scan line is the
             first to be displayed
------------------------------------------------------------
Port-Index: 09h              Port: 03d4h, 03b4h
usage:      Maximum scan line/Character height
            d7    double scan
            d6    bit d9 of line compare register
            d5    bit d9 of start vertical blank register
            d0-d4 Maximum scan line
Description: d0-d5=Character height-1,  only in textmodes
------------------------------------------------------------
Port-Index: 0ah              Port: 03d4h, 03b4h
usage:      Cursor start
            d7,d6 Reserved (0)
            d5    Cursor off
						d4-d0 Cursor start
Description:
------------------------------------------------------------
Port-Index: 0bh              Port: 03d4h, 03b4h
usage:      Cursor end
						d7    reserved
            d6,d5 Cursor skew
            d4-d0 Cursor end
Description:
------------------------------------------------------------
Port-Index: 0ch              Port: 03d4h, 03b4h
usage:      Start address high
------------------------------------------------------------
Port-Index: 0dh              Port: 03d4h, 03b4h
usage:      Start address low
Description: Determine the offset in display memory to be
             displayed on the upper-left corner on the screen
------------------------------------------------------------
Port-Index: 0eh              Port: 03d4h, 03b4h
usage:      Cursor location (high byte)
------------------------------------------------------------
Port-Index: 0fh              Port: 03d4h, 03b4h
usage:      Cursor location (low byte)
Description: Where the cursor is displayed on screen
------------------------------------------------------------
Port-Index: 10h              Port: 03d4h, 03b4h
usage:      Vertical retrace start
Description: 8 bits out of 10
------------------------------------------------------------
Port-Index: 11h              Port: 03d4h, 03b4h
usage:      Vertical retrace end
            d7    Write protect CRTC register 0 to 7
            d6    refresh cycle select
            d5    enable vertical interrupt (when 0)
            d4    Clear vertical interrupt (when 0)
            d0-d3 Vertical retrace end
------------------------------------------------------------
Port-Index: 12h              Port: 03d4h, 03b4h
usage:      Vertical display enable end
Description: eight LSB bits out of ten-bit value which define
             scan line minus one at which the display ends.
						 The other two are in CRTC register index 7
------------------------------------------------------------
Port-Index: 13h              Port: 03d4h, 03b4h
usage:      Offset / Logical screen width
Description: Logical screen width between successive scan lines
------------------------------------------------------------
Port-Index: 14h              Port: 03d4h, 03b4h
usage:      Underline location register
            d7    Reserved
            d6    Double word mode
            d5    count by 4
            d0-d4 Underline location
Description: Underline location: Monochrome textmode only
------------------------------------------------------------
Port-Index: 15h              Port: 03d4h, 03b4h
usage:      Start vertical blanking
Description: eight LSB bits of ten-bit value minus one which
             define at which scan line the vertical blanking
						 starts. The other two bits are in CRTC registers
             index 7 and 9
------------------------------------------------------------
Port-Index: 16h              Port: 03d4h, 03b4h
usage:      End vertical blanking
Description: eight LSB bits of a value which determine the scan
             line after which vertical blanking ends.
------------------------------------------------------------
Port-Index: 17h              Port: 03d4h, 03b4h
usage:      Mode control register
            d7  Enable vertical and hoizontal retrace
            d6  Byte mode (1), word mode (0)
            d5  Address wrap
						d4  Reserved
            d3  count by 2
            d2  multiple vertical by 2 (use half in
                CRTC (8,10,12,14,18)
            d1  Select row scan counter (not used)
						d0  compatibilty mode support (enable interleave)
------------------------------------------------------------
Port-Index: 18h              Port: 03d4h, 03b4h
usage:      Line compare register
Description: Split screen,  8 bit value out of a ten-bit value
------------------------------------------------------------
Port-Index: 00h              Port: 03c4h
usage:      Reset register
            d7-d2 Reserved
            d1    Synchronous reset
            d0    Asynchronous reset
Description: Synchr. when set to zero, will halt and reset
             the sequencer at the end of its current cycle
						 Asyncht. when set to zero, will immediatly halt
             and reset the sequencer. Data can be loss.
------------------------------------------------------------
Port-Index: 01h              Port: 03c4h
usage:      Clock mode register
						d7,d6 Reserved
            d5    display off
            d4    Allow 32-bit Fetch (not used in standard modes)
            d3    Divide dot clock by 2 (used in some 320*200 modes)
            d2    Allow 16-bit fetch (used in mon graphics modes)
            d1    Reserved
            d0    Enable (0) 9 dot characters (mono text and 400-line)
Description: Display off: Will blank screen and give the cpu
             uninterrupted access the display memory.
------------------------------------------------------------
Port-Index: 02h              Port: 03c4h
usage:      Color plane write enable register
            d7,d6 Reserved
						d3    Plane 3 Write enable
            d2    Plane 2 Write enable
            d1    Plane 1 Write enable
            d0    Plane 0 Write enable
Description:
------------------------------------------------------------
Port-Index: 03h              Port: 03c4h
usage:      Character generator select register
            d7,d6 Reserved
            d5    Character generator table select A (MSB)
            d4    Character generator table select B (MSB)
            d3,d2 Character generator table select A
            d1,d0 Character generator table select B
Description: This register is only of interest if your software
             will be using multiple character sets. Either one
             or two character sets can be active. Table A selects
             the charcater with attribute d3 set to zero and
             Table B is the one with d3 set to one.
------------------------------------------------------------
Port-Index: 04h              Port: 03c4h
usage:      Memory mode register
            d4-d7 Reserved
            d3    Chain 4 (address bits 0&1 to select plan, mode 13h)
						d2    Odd/even (address bit 0 to select plane 0&2 or
                  1&3 text modes)
            d1    Extended memory (disable 64k modes)
            d0    Reserved
Description:
------------------------------------------------------------
Port-Index: 00h              Port: 03ceh
usage:      Set / Reset register
            d7-d4 Reserved (0)
            d3    Fill data for plane 3
            d2    Fill data for plane 2
            d1    Fill data for plane 1
            d0    Fill data for plane 0
------------------------------------------------------------
Port-Index: 01h              Port: 03ceh
usage:      Set / Reset enable register
            d7-d4 Reserved (0)
            d3    enable set/reset for plane 3 (1 = enable)
						d2    enable set/reset for plane 2 (1 = enable)
            d1    enable set/reset for plane 1 (1 = enable)
            d0    enable set/reset for plane 0 (1 = enable)
Description: Set/Reset enable defines which memory planes will
             receive fill data from set/reset register. Any plane
             that is disable for set/reset will be written with
             normal processor output data
------------------------------------------------------------
Port-Index: 02h              Port: 03ceh
usage:      Color compare register
            d7-d4 Reserved
            d3    Color compare value for plane 3
            d2    Color compare value for plane 2
						d1    Color compare value for plane 1
            d0    Color compare value for plane 0
Description: one indicate that color is the same
------------------------------------------------------------
Port-Index: 03h              Port: 03ceh
usage:      Data rotate / Function select register
            d7-d5 Resrved (0)
            d4,d3 Function select
            d2-d0 Rotate count

            d4 d3  Function
            0  0   Write data unmodified
            0  1   Write data ANDed with processor latches
            1  0   Write data ORed with processor latches
            1  1   Write data XORed with processor latches
Description: Rotation is made before writing data
------------------------------------------------------------
Port-Index: 04h              Port: 03ceh
usage:      Read plane select register
            d7-d2 Reserved (0)
            d1,d0 Defines color plane for reading (0-3)
Description: Doesnt matter in color compare mode
------------------------------------------------------------
Port-Index: 05h              Port: 03ceh
usage:      Mode register
            d7    Reserved (0)
            d6    256-colour mode
            d5    Shift register mode
            d4    Odd / Even mode
            d3    Color compare mode enable (1 = enable)
            d2    Reserved (0)
            d1,d0 Write mode

            d1 d0 Write mode
            0  0  Direct write (data rotate, set/reset may apply)
            0  1  Use processor latches as write data
						1  0  Color plane n (0-3) is filled with the value of
                  bit n in the write data
            1  1  Use (rotated) write data ANDed with Bit mask as
                  bit mask. Use set/reset as if set/reset was
                  enable for all planes
Description:
------------------------------------------------------------
Port-Index: 06h              Port: 03ceh
usage:      Miscellaneous register
            d7-d4 Reserved
            d3-d2 Memory map
                  00 = A000h for 128k
                  01 = A000h for 64k
                  10 = B000h for 32k
                  11 = B800h for 32k
            d1    Odd/even enable (used in text modes)
            d0    Graphics mode enable
Description: Memory map defines the location and size of the
						 host window
------------------------------------------------------------
Port-Index: 07h              Port: 03ceh
usage:      Color don't care register
            d7-d4 Reserved (0)
						d3    Plane 3 don't care
            d2    Plane 2 don't care
            d1    Plane 1 don't care
            d0    Plane 0 don't care
Description: Color don't care is used in conjunction with color
             compare mode. This register masks particular planes
             from being tested during color compare cycles.
------------------------------------------------------------
Port-Index: 08h              Port: 03ceh
usage:      Bitmask register
Description: The bitmask register is used to mask certain bit
             positons from being modified.
------------------------------------------------------------
Port-Index: -                 Port: 03c0h both index and data
usage:      d7,d6 Reserved
            d5    Palette address source
                  0 = palette can be modified, screen is blanked
                  1 = screen is enable, palette cannot be modified
						d4-d0 Palette register address
Description: Palette register address selects which register of
             the attributes controller will be addres,sed by the
             next I/O write cycle
------------------------------------------------------------
Port-Index: 00h-0fh          Port: 03c0h
usage:      Color palette register
            d6,d7 Reserved
            d5-d0 Color value
Description: not used in 256 color modes
------------------------------------------------------------
Port-Index: 10h              Port: 03c0h
usage:      Mode control register
						d7  p4,p5 source select
            d6  pixel width
            d5  Horizontal panning compatibility
            d4  Reserved
            d3  Background intensify / enable blinking
						d2  Line graphics enable (text modes only)
            d1  display type
            d0  graphics / text mode
Description: p4,p5 source select: selects the source fZ              outputs p4 and p5 to the DACs. If set to zero, p4
              and p5 are driven from the palette registers (normal
              operation). If set to one, p4 and p5 video outputs
              come from bits 0 and 1 of the color select register.
             pixel width: is set to one in mode 13h (256-color mode)
             horizontal panning compatibility: enhances the
              operation of the line compare register of the CRT
              controller, which allows one section of the screen
              to be scrolled while another section remains stationary.
              When this bit is set to one, the stationary
							section of the screen will also be immune to horizontal
              panning.
------------------------------------------------------------
Port-Index: 11h              Port: 03c0h
usage:      Screen border color
Description: In text modes, the screen border color register
             selects the color of the border that sorrounds the
             text display area on the screen. This is also referred
             to by IBM as overscan. Unfortunately, this feature
             does not work properly on EGA displays in 350-line
             modes.
------------------------------------------------------------
Port-Index: 12h              Port: 03c0h
usage:      Color plane enable register
            d7,d6 Reserved
            d5,d4 Video status mux
            d3    Enable color plane 3
            d2    Enable color plane 2
						d1    Enable color plane 1
            d0    Enable color plane 0
Description:  The video status mux bits can be used in conjunction
             with the diagnostic bits of input status register 1
             to read palette registers. For the EGA, this is the
						 only means available for reading the palette registers.
              Enable color planes can be used to enable or disable
             color planes at the input to the color lockup table.
             A zero in any of these bit positions will mask the
             data from that color plane. The effect on the display
             will be the same as if that color plane were cleared
             to all zeros.
------------------------------------------------------------
Port-Index: 13h              Port: 03c0h
usage:      Horizontal panning register
            d7-d4 reserved
            d3-d0 Horizontal pan
Description: Horizontal pan allows the display to be shifted
						 horizontally one pixel at a time.

             d3-d0      Number of pixels shifted to the left
                        0+,1+,2+     13h     Other modes
                        3+,7,7+
						 0          1            0       0
             1          2            1       -
             2          3            2       1
             3          4            3       -
             4          5            4       2
             5          6            5       -
             6          7            6       3
             7          8            7       -
             8          9            -       -
------------------------------------------------------------
Port-Index: 14h              Port: 03c0h
usage:      Color select register
            d7-d4 Reserved
						d3    color 7
            d2    color 6
            d1    color 5
            d0    color 4
Description:  Color 7 and color 6: are normally used as the high
						 order bits of the eight-bit video color data from the
             attribute controller to the DACs. The only exceptions
             are 256-color modes
              Color 5 and color 4: can be used in place of the p5
             and p6 outputs from the palette registers (see mode
             control register - index 10h). In 16-color modes, the
             color select register can be used to rapidly cycle
             between sets of colors in the video DAC.
------------------------------------------------------------
Port-Index: -                Port: 03c6h
usage:      Pixel mask register
Description: ???
------------------------------------------------------------
Port-Index: -                Port: 03c7h
usage:      DAC state register (read-only)
Description: if d0 and d1 is set to zero it indicates that
             the lookup table is in a write mode
------------------------------------------------------------
Port-Index: -                Port: 03c7h
usage:      Lookup table read index register (Write only)
Description: Used when you want to read the palette (set color
             number)
------------------------------------------------------------
Port-Index: -                Port: 03c8h
usage:      Lookup table write index register
Description: Used when you want to change palette (set color
             number)
------------------------------------------------------------
Port-Index: -                Port: 03c9h
usage:      Lookup table data register
Description: Read color value (Red-Green-Blue) or write same data.

--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER     IBM FAQ        Sound Cards
--------------------------------------------------------------------------------
Q2.1    How do I program my XXX?

    This question is asked a lot, there is information available
    for the adlib, but for many of the NEWER cards this is a
    problem.  The suggestion of rec.games.programmers is to read
    the pc sound card group or the pc demos group.  Why?  Too
    many cards unless someone else wishes to get the information
    and make YAF! (yet another FAQ)

--------------------------------------------------------------------------------
END OF FAQ




Article 17548 of rec.games.programmer:
Newsgroups: rec.games.programmer
Path: usenet.ucs.indiana.edu!vixen.cso.uiuc.edu!howland.reston.ans.net!news.intercon.com!panix!ddsw1!news.kei.com!ub!acsu.buffalo.edu!pleung
From: pleung@cs.buffalo.edu (Patrick Leung)
Subject: REPOST:  Mode X FAQ, part 2/2
Message-ID: <Cp3uE7.9EA@acsu.buffalo.edu>
Sender: nntp@acsu.buffalo.edu
Nntp-Posting-Host: gagarin.cs.buffalo.edu
Organization: State University of New York at Buffalo/Comp Sci
Date: Sun, 1 May 1994 03:44:30 GMT
Lines: 1087

Article 21306 of rec.games.programmer:
Path: acsu.buffalo.edu!ub!toz!news
From: cyberman@toz.buffalo.ny.us
Newsgroups: rec.games.programmer
Subject: RGP FAQ
Message-ID: <gate.75gkHc1w165w@toz.buffalo.ny.us>
Date: Fri, 11 Feb 94 00:01:28 EST
Organization: TOZ automated posting

Revision 0.0.5  of REC.GAMES.FAQ

This document will be made available by mail request at a later
date (mail server difficulties).  You may attempt to see if this
mail server works by sending to:

    aser@toz.buffalo.ny.us

I cannot be sure it's working yet,  please leave feedback on what
state it is in.

There are currently 3 FAQ's

RGP.FAQ - rec.games.programmer General FAQ
RGP.IBM - rec.games.ibm relevant FAQ
MAZE.FAQ - FAQ about MAZE's (more of a compilation of articles)

This was done so that someone who is looking for more general
information will be able to find game programing information
without being inundated by IBM, other computer-SPECIFIC
information, or the topsy turvey world of maze generation.

The current Editor is Cyberman@toz.buffalo.ny.us

--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER     General FAQ     Contents
--------------------------------------------------------------------------------
LEGAL

This document is FREE!  It is for your self enlightenment.  No
warranty is provided nor implied with this information. The
accuracy of the information contained herein is subject to
conjecture.  Therefore the editor and contributers will take NO
liability for improper use, misuse, or abuse of this information,
and any damage to ANYTHING or ANYONE whether physical, financial,
etc. in no way, shape, or form can be attributed to this
document. Use this information at your OWN risk.

The above statement is to keep those who contributed and the
editor free from personal injury for being nice.

Special thanks to:
andrean@cs.utexas.edu (Andre A. Nurwono)
roberts@brahms.amd.com (Dave Roberts)
sean@stat.tamu.edu (Sean Barrett)
Cyberman@toz.buffalo.ny.us (Cyberman)
(and anyone else I forgot to mention for that matter)

If you wish to contribute CODE be sure it's something you DO NOT
wish to COPYRIGHT!

All contributions and suggestions should be sent to me at:
Cyberman@toz.buffalo.ny.us
place in subject header

RGP.FAQ.*
where * is any of the following
    SUGGESTION      - to suggest Adding an area (I recommend that
                        you send the information if you want it
                        added)
    ADD             - an addition (ie TBA's [see KEY for what TBA
                        means])
    EDIT            - for a correction somewhere (it is suggested
                        contributers do there own editing)
    FLAME           - complaints - I'll read these but be sure to
                        be tasteful in you commentary.  You may or
                        may NOT get a reply.

For now I'm going to use my personal mail account.  So please be
careful.

Format:
There are several categories and each category contains it's
relevant questions as suggested.

Key:
TBA - To Be Added

[Frequently Asked Questions about terminology]
Q1.1    What are .MOD files?
Q1.2    What is a pixel?
Q1.3    What is a bitmap?
Q1.4    What is flicker?
Q1.5    What is snow?
Q1.6    What is a frame buffer?
Q1.7    What is a Sprite?
Q1.8    What is vertical/horizontal retrace?

[Frequently Asked Questions about Animation]
Q2.1    How do I make sprites on my xxx?
Q2.2    What about collision detection?             TBA
Q2.3    What about bitmap scaling?                  TBA
Q2.4    What is perspective mapping?                TBA
Q2.5    What about 3d objects and manipulation?

[Frequently Asked Questions about Map Generation]
Q3.1    How do I generate a maze?
Q3.2    How do I generate a landscape/terrain?      TBA
Q3.3    How do I generate a hex map?                TBA
Q3.4    What about random number generators?

[Frequently Asked Questions about Libraries and support software]
Q4.1    What is there for the IBM compatible?
Q4.2    "    "  "     "   "   Amiga?                TBA
Q4.3    "    "  "     "   "   Atari?                TBA
Q4.4    "    "  "     "   "   Macintosh?            TBA
Q4.5    "    "  "     "   "   Sun/Sparc?
Q4.6    "    "  "     "   "   X?                    TBA

[Frequently Asked Question about Where is ...]
Q5.1    Where is Joshua Jensens famous Perspective Mapping Code?
Q5.2    Where else should I read?
Q5.3    Where can I find out about ray traceing?

Note 1: Fixing snow and flicker
Note 2: 2 Part Tutorial on 3d graphics

--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER     General FAQ     Terminology
--------------------------------------------------------------------------------

Q1.1    What are .MOD files?
    A .MOD file is a file generated for the Amiga.  A tracker is
    used to play the MOD.  A mod consists of digitized sound and
    sequencing information to play music.  Here is a BRIEF and
    incomplete text file that is somewhat informative on the
    subject.

    Note - Joshua Jensen has written a mod player that can be
    linked into your code.  So has the author of mod play.

    SEE ALSO - Mod Format specification file.  (Modform.zoo)

Q1.2    What is a Pixel?

    Pixel is short for Picture Element.  It is a single dot
    address on a grid used to display images on a monitor (Tv
    included).

Q1.3    What is a bitmap?

    A bitmap aka bitimage is the representation of an image in
    the form of a sequence of bits.  For example most graphic
    modes on computers represent the pixels using a BITMAP.

Q1.4    What is flicker?
    Flicker is a noticeable pulse or change in an image.  This
    can be on a CRT (Cathode Ray Tube) or other type display
    device.  The cause is that the refresh rate of the CRT is
    lower than the persistance of vision of the person observing
    it.

    Another form of flicker is due to rapid drawing of data on
    the screen.  What happens is that the data is drawn out of
    syncronization with the horizontal and vertical scan.  So
    your image apears to fade in and out of visability.

    SEE ALSO fixing snow and Flicker

Q1.5    What is SNOW?

    Snow are small specals on the screen that appear like SNOW
    falling on the screen (hence the name).

    Snow is caused by a number of things.  One of which is when
    one is writting to the screen while the display card is
    scanning that address of the screen, this causes a conflict
    and can produce random specals.

    Another cause of snow is an improperly connected monitor.
    This can damage the monitor.  Yet another source is noise
    from an electro magnetic source, if indeed it's not from
    anything you own the FCC might need to be notified.

    SEE ALSO fixing snow and Flicker

Q1.6    What is a frame buffer?

    Memory that contains image data that is translated to the image
    on your screen.  A frame buffer does not have to be
    "visible".  Also the methode of this tranformation is not
		always the same, so no effort here will be made to explain
    further.
 
Q1.7    What is a Sprite?

    A sprite is an image usually moveable about the screen.
    Common information stored in a sprite are, width, height,
    position, and image data.  A sprite ussually does not effect
    the screen background, this is of course dependant on
    implementation.
 
Q1.8    What is vertical/horizontal retrace?

    Most monitors are what is called a RASTER display.  This
    means that an image is represented by setting the intensity
    of a grid of dots on the display.  Each dot is called a
    pixel.  In order to display the grid a CRT sweeps an electron
    beam across the display surface sending pulses corresponding
		to the intensity of the pixel.  However the stream of video
    information is almost always represented left to right top to
    bottom.  This mean that the beam must scan across the screen
    and then move BACK to start a line.  This is called
    Horizontal retrace.

    Vertical retrace is when the beam finishes painting the
    screen from top to bottom again the beam must be moved to the
    top of the screen.

    The horizontal sweep is controlled by an electric field the
    vertical sweep is controlled usually magnetic field.

--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER     General FAQ     Animation
--------------------------------------------------------------------------------

[Frequently Asked Questions about Animation]
Q2.1    How do I make sprites on my xxx?

    This, unfortunately, is a rather complex problem and its
    implementation is often computer-specific, however some of it
    can be addressed in the general FAQ.

    Sprites require one to copy pixels to the display in a
    certain area of the screen.  There are various issues that
    must be addressed about this.

    Getting and Putting an image: getting means you copy a
    section of a screen (bitmap) to a buffer, putting means you
    dump a buffer of data (bitmap) to a screen location.  These
    are often used for less sophisticated sprite animation.

    The problem with this technique is put destroys the
    background information.  So if you want a background at all,
    there must be a way to "overlay" an image onto it without
		causing a large area around the sprite to disappear. An old
    way of "fixing" this is to copy the background of an image
    before you destroy it, then put the background back after you
    move it.

    Another methode of sprite creation requires custome hardware
    (Amiga C64 Atari 8bits).

Q2.2    What about collision detection?                 TBA
Q2.3    What about bitmap scaling?                      TBA
Q2.4    What is perspective mapping?

    What is it?  Basically it takes an image and "pastes" it in
    3d perspective onto a surface.  This is much faster than
    rendering surfaces in real time.  Article 7716 of r.g.p
    written by Joshua C. Jensen (sl8nl@cc.usu.edu) is an example
    of this technique (implemented in Turbo Pascal).
    Unfortunately this article # may not corespond to anything in
		usenet! :)  However the date it was posted was 1 Aug 92
    01:36:51 GMT.  SO you can grab the coresponding articles
    there! :)

Q2.5    What about 3d objects and manipulation?

    Note 2 is a pair of tutorials on this subject.

    Another suggestion is to check comp.graphics FAQ and the
    comp.graphics resources guide as well.

--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER     General FAQ     Map Generation
--------------------------------------------------------------------------------

Q3.1    How do I generate a maze?

    This is a VERY frequently asked question in rgp so we have
		a unoffical maze FAQ.  It's is now posted WITH the RGP Faq.

Q3.2    How do I generate a landscape/terrain?
    Another fun filled FAQ it has too many answers.  A suggestion
    is to read sci.fractals.  Now if someone would conribute some
    information on this I would be happy to construct the
    "land.faq".

Q3.3    How do I generate/use a hex map?
    Well this has discussed considerably on rgp.  We haven't a
    FAQ for it until I get permission to use something I
    captured.

Q3.4    What about random number generators?
    These are mandatory for making a "new" universe each time a
    program loads.  Usually the ones included in a C compiler 
    library are sufficient for most needs.  However sometimes one
    must go the extra mile and use there own random number
		generator.  Currently we have no FAQ on random number
    generators.  (sorry)

--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER     General FAQ     Libraries and support software
--------------------------------------------------------------------------------

Q4.1    What is there for the IBM and Compatibles?

    There is a lot.  I suggest scrounging around wuarchive
    personally, but here is a terse UNOFFICIAL list!

    contributed by
andrean@cs.utexas.edu (Andre A. Nurwono)
==========
 --------
 Graphics
 --------

*.  Executable
    File(s) : TWEAK06.ZIP
    Who     : Robert Schmidt (robert@solan.unit.no)
    When    : 1992
    What    : A program to experiment w/ VGA registers, very useful
	      if you want to define new modes (like mode X & 360x400 modes)
    Where   : simtel & mirrors
 
*.  Executable, (source code)
    File    : SPRITE.ZIP
    Who     : Billy Dalrymple
    When    : 1989
    What    : A sprite editor, produces sprites w/ mask in files.
	      info available for $10
	      source code available for $25
    Where   : I forget
 
*.  Executable, Source Code
    File(s) : VGA.ZIP
    Who     : wardt@a.cs.okstate.edu
    When    : 1992
    What    : A sprite editor, includes full source (.ASM & .C)
    Where   : I forget 
 
*.  Source Code, Library
    File(s) : DDJ****.ZIP, XSHARP**.ZIP
    Who     : M. Abrash
    When    : Aug-Dec 1991, Jun-Aug 1992
    What    : Mode X introduction. Sources to do animation,
	      polygon plotting, anti-aliasing, etc, on Mode X.
    Where   : SIMTEL and mirrors, 
	      ftp.mv.com (Official DDJ site) in pub/ddj
 
*.  Source Code
    File(s) : article 7198 of rec.games.programmer
		Who     : Frederick J. Haab (otto@nevada.edu)
    When    : 26 Jun 92 00:17:52 GMT
    What    : Scrolling in mode 13h, C program
    Where   : USENET archives
 
*.  Source Code
    File(s) : article 7716 of rec.games.programmer
    Who     : Joshua C. Jensen (sl8nl@cc.usu.edu)
    When    : 30 Jul 92 00:02:36 GMT
    What    : Bitmap manipulation (scaling + perspective), Turbo Pascal
	      source w/ inline assembly.
    Where   : USENET archives
 
*.  Source Code
    File(s) : VESAVGA.ZIP
    Who     : Randy Buckland
    When    : 6/18/92
    What    : .ASM & .C source to provide fast routines for VESA VGA modes.
		Where   : garbo
 
*.  Sprite Library, Code
    File(s) : STK110.LZH
    Who     : Jari Karjala
    When    : 1991 (v 1.1)
    What    : Sprite library & toolkit for Hi-Res EGA, BW
	      includes C source, demo & good docs.
    Where   : simtel & mirrors
 
*.  Sprite Library, Source Code
    File    : SPRITES.ZIP
    Who     : Marius Kjeldahl
    When    : 1991
    What    : Sprite library for VGA mode $13
	      includes TPU, .PAS source.
	      (shareware, $69 ?)
    Where   : garbo

*.  Sprite Library, Toolkit
    File(s) : WGT_SPR2.ZIP, WGT_TC21.ZIP, WGT_TP2.ZIP
    Who     :
    When    : 1992
    What    : Shareware Sprite toolkit for VGA mode $13
              includes TPU (WGT_TP2.ZIP), example programs for usage
	      Nag-shareware program
    Where   : wuarchive, if somebody hasn't erased it yet

*.  Library (Pascal)
    Files   : EGOF10.ZIP, EGOF10P.ZIP, EGOF10M.ZIP,
              EGOF10B.ZIP, EGOF106.ZIP
    Who     : Logi Ragnarsson
    When    : 1993
    What    : 256-colour graphics library for Turbo/Borland Pascal 6.0
              and 7.0, VESA SVGA, Mode-X (and more), VGA/MCGA 320x200,
              example programs, manual, shareware ($20).
		Where   : garbo

*.  Library Source
    File(s) : Xlib04c.zip
    Who     : Themie Gouthas (and company)
    When    : 11 Mar 93
    What    : mode X library for game, to many feature to mention
    Where   : pub/MSDOS_UPLOADS@wuarchive.wustl.edu
 
 -------------
 Sound & Music
 -------------
 
*.  Documentation
    File(s) : Article 6077 of rec.games.programmer
    Who     : Jeffrey S. Lee (jlee@smylex.uucp)
    When    : 25 Feb 92 15:02:02 GMT
    What    : Programming the AdLib/Sound Blaster FM Music Chips
		Where   : usenet archives, also at the SB project site
	      (tybalt.cco.caltech.edu), & SB mailserver
	      (listserv@porter.geo.brown.edu)
 
*.  Executable, Runtime Library
    File(s) : MODTECH.ZIP
    Who     : Mark J. Cox (M.J.H.Cox@bradford.ac.uk)
    When    : 1991
    What    : TSR Library to play .MOD files in the background
	      Supports PC Speaker, SB, DisneySS, LPT DACs, etc
    Where   : ftp.brad.ac.uk in /misc/msdos/mp

*.  Library
    File(s) : MODOBJ.ZIP
    Who     : Mark J. Cox (M.J.H.Cox@bradford.ac.uk)
    When    : 1992
    What    : .OBJ file w/ routines to play .MOD files in the background
	      Supports PC Speaker, SB, DisneySS, LPT DACs, etc
				Includes examples in TC & TP
	      (shareware, $30)
    Where   : ftp.brad.ac.uk in /misc/msdos/mp
 
*.  Source code
    File(s) : NH10SRC.ZIP
    Who     :
    When    :
    What    : Eliminate noise on sound samples, incl. .C source
    Where   : SB project site & mailserv site
 
*.  Source code, Executable
    File(s) : SB_OSC.ZIP
    Who     :
    When    :
    What    : SB input scope / oscillator. Incl. .ASM source
    Where   : SB project site & mailserv site
 
*.  Source code, Executable
    File(s) : SBDAC.ZIP
    Who     : Jeff Bird (cejjb@marlin.jcu.edu.au)
    When    : 12 Feb 92
    What    : SB DAC programming using DMA. Incl. .ASM & .C source
    Where   : I forget (probably on SB project sites too)

==========

Q4.2    "    "  "     "   "   Amiga?                TBA

Q4.3    What is there for the Atari?

from warwick@cs.uq.oz.au

    AMS library - Atari Machine Specific library
      - C++ classes for Sprites, Screen, Joysticks, Double buffering, etc.
      - beta testing now
			- contact: warwick@cs.uq.oz.au

Q4.4    "    "  "     "   "   Macintosh?

from jmunkki@vipunen.hut.fi

*. Source code
    Files   : Arashi_Source.cpt.bin
    Who     : ???
    When    : ???
    What    : source code for an arcade quality game, vector
        graphics, multichannel sound, (no sprites)
    Where   : pub/mac/think-c/code@ics.uci.edu

Q4.5    "    "  "     "   "   Sun/Sparcs?

    contributed by
andrean@cs.utexas.edu (Andre A. Nurwono)
==========
 --------
 Graphics
 --------
*.  Library
    What    : Standard PIXRECT library
	      Bitmap manipulation routines for frame buffer.
 
 -------------
 Music & Audio
 -------------
*.  Source code
    File(s) : tracker.tar.Z
    Who     :
    When    :
    What    : .MOD file player through the audio device. Works on SPARCS
	      w/ audio devices.
    Where   :

*.  Source code
    File(s) : csound.tar.Z
    What    : FFT & signal processor
 
*.  Source code
    What    : MixView
==========

Q4.6    "    "  "     "   "   X                     TBA

    Additions are welcome.

--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER     General FAQ     FAQ's about Where is ...
--------------------------------------------------------------------------------

Q5.1    Where is Joshua Jensens famous Perspective Mapping Code?

    Beats me no one has found it yet (or at least hasn't told me
    they have and where to get it!) in one of the many usenet
    archive sites.  Places to look are gatekeeper.com and
    wuarchive.wustl.edu.  Both of these ftp sites archive usenet
    news.  I suspect all the rec.games.programmer articles are on
    these sites and maybe (heavem forbid) the original FAQ even.

Q5.2    Where else should I read?

    Here are SUGGESTED places you get information for things like
    perspective mapping programming the SB etc.
    
        comp.graphics
        comp.graphics.animation
        comp.sys.ibm.pc.soundcard

    I suggest before posting you read ALL newsgroups a minimum of
		1 week.  Ussually you will see the FAQ or where to get it.

    places suggested NOT to look for information

        comp.graphics.research

        if you want to get famed for posting off topic do it
        there.  That group is for research IE new frontiers.

Q5.3    Where can I find out about ray traceing?

    Ask about POV in comp.graphics should be good for about 30 to
    40 replies in your mailbox.  There are several packages
    available for free and comercially.  I suggest POV because
    it's free and actually quite good.  Vivid, Rayshade are just
    a few of the others.  POV seems to be the most popular (and
    portable also), with the most handy utilities.

--------------------------------------------------------------------------------
END OF FAQ

--------------------------------------------------------------------------------
REC.GAMES.PROGRAMMER     General FAQ     NOTES
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
NOTE 1: contributed by
--------------------------------------------------------------------------------
sean@stat.tamu.edu (Sean Barrett)

There are two things that qualify as flicker.  Well, hell, to make it
simpler, let's call it three.  At the end of this list I'll give a
rough definition of the problem.

1)	You move a shape by erasing it and plotting it in a new position,
and there is a screen refresh during the time it is erased, resulting in
the background showing through.

2)	You're using CGA and you try to write anywhere on the screen
during retrace, causing "noise" (due to DMA problems, I guess?).

3)	You're moving a shape by some sort of "one-pass" technique in which
the screen memory is never set to the background temporarily, so (1)
can't happen, but the screen area the shape is in is refreshed during
the draw, so half of it gets displayed at the old location, and half
at the new.

I think a general rule would be that flicker occurs when a pixel on
the screen is displayed with a color other than the "correct" or
"intended" pixel value, as compared to an ideal "intended" case.  (Thus,
if you're simulating something moving, you shouldn't see the
background; if you're trying to simulate something moving and
turning on and off simultaneously, then you should see it; it's
all a question of intent.)

Back to the above problems.

Now, so far as I know, there are only two solutions to #2.  Only redraw
during the vertical retrace (blank), or don't support CGA.  So I'm going
to forget about this problem.

You can handle #1, as I suggested in #3, by simply making sure you never
write to the screen a value you don't want displayed.  Below I'll put a
list of ways I can think of to do this for bitmapped graphics--i.e.,
how to avoid the erase-redraw cycle.

If you really want to handle #3, then things get funky, and more power
to you.  I don't personally believe it's a problem.  If it's periodic,
so this one shape when you move it horizontally in the middle of the
screen is always split with the top half leading the bottom half by
a pixel, it's a problem; but if it just happens randomly once in a while
I doubt it's noticeable.  In general, though, the solutions require
paying attention to where the screen refresh is in some way.  My main
point, the reason I'm posting this whole thing, is that *solving problem
#1 does not require messing with knowing what section of the screen
is being refreshed.*  As far as I know, the methods to combatting #3
are to redraw everything during vertical refresh (same as #2, but
overkill) or drawing your shapes from top to bottom lagging about half
the time of a screen refresh behind the refresh, or some such.

Solutions to #1 that don't require timing considerations, e.g., how
never to write a wrong pixel to the screen.

  o	Don't use raw bitmaps, use sprite hardware.

  o	Use hardware page flipping: display one screen, draw a new
	screen "off-screen" and when it's finished, direct the
	display hardware to display the new one.  This can get messy
	for fast animation because you have to keep track of where
	sprites were the last two frames to erase and update them.

  o	Use software page flipping; display one screen, draw a new
	screen "off-screen" and when it's finished, copy the new
	screen into screen memory.

  o	Use techniques such as "store" sprites which overwrite the
	background.  Generally an out-of-date technique now, though;
	only works for mono-color backgrounds.  You simply write the
	sprite onto the screen; the sprite has enough border around
	it to overwrite its previous image.  This is gross, very
	fast, and flicker-free except when shapes get on top of each
	other, at which point you get massive flicker.

  o	Use scratch-pad calculations, a variant of software page flipping.
	Copy the section of the screen off that you need to update,
	update it offscreen, and put it back on the screen.  A lengthy
	time ago I posted a discussion of how to do this effectively
	for XOR-style graphics for 8-bit type machines--you can xor
	a single image onto the screen that both erases and replots
	in a new place the old sprite.  And you can calculate the
	image to do it on the fly, without additional memory, if you
	set up your shape tables, and it's faster than the normal
	draw shape with XOR to erase, draw shape with XOR to plot cycle
	because it only reads and writes screen memory once.

Performance enhancements for bit blitting:

  o	Unroll loops.

  o	Write a custom bit blit for each shape, dedicated to that shape.
	Cuts your memory accessing down if the machine has an
	"immediate" operand mode that's faster than an index-addressed
	one.

Memory performance enhancements for techniques that require many copies
of shapes or large routines (such as pre-shifted shape tables):

  o	If you're only using some of your shapes at any point in time
	(e.g. if you can divide your display up into "scenes"; for a
	certain period of time only these shapes are used), calculate
	the "larger" derived tables on the fly when the scene starts
	up.  For large games (this is rec.games.programmer, not
	rec.graphics.programmer, right?) that have to access the disk
	anyway to change scenes, this is no big time loss.  Also, if
	you write the code right then while you're idling the processor
	before starting work on the next display, you can do this stuff
	then.

--------------------------------------------------------------------------------
NOTE 2: contributed by
--------------------------------------------------------------------------------
sean@stat.tamu.edu (Sean Barrett)

3D graphics: Using matrices and vectors		Part 1


-  Allows you to independently rotate objects and move the camera
   anywhere.
-  Does not discuss clipping.
-  Algorithm uses 9 multiplies, 2 divides, and 9 additions per point,
   plus overhead per independently located object.
-  Part 2 gives the derivation for these formulas.


Assume a right-handed universe, with x horizontal, y
depth, and z vertical, and a screen display unit with
x horizontal to the right and y vertical downward.


The following are the rotation matrices:

	Rx(t)			Ry(t)			Rz(t)
__                  __  __                  __  __                  __
| 1    0      0    0 |	| cos(t) 0 -sin(t) 0 |	|  cos(t) sin(t) 0 0 |
| 0  cos(t) sin(t) 0 |	|    0   1    0    0 |	| -sin(t) cos(t) 0 0 |
| 0 -sin(t) cos(t) 0 |	| sin(t) 0  cos(t) 0 |	|    0	    0    1 0 |
| 0    0      0    1 |  |    0   0    0    1 |  |    0      0    0 1 |
--                  --  --                  --  --                  --
   rotate about x	   rotate about y	   rotate about z


The following is the translation matrix:

  T(a,b,c)
__       __
| 1 0 0 a |
| 0 1 0 b |
| 0 0 1 c |
| 0 0 0 1 |
--       --

Let each object be a collection of points or lines.  If lines, they
are drawn as lines connecting two 3D points, which can each be
individually transformed.  So this derivation just handles converting
individual points in three-space into pixel coordinates.

---- BEGIN FORMULAS ----

If d is the distance from the eye to the window, h is the width
of the window, v is the height of the window (use the sizes
of the actual display if you don't know what else, but this is
actually referring to the virtual camera's window); num_x
is the number of pixels on the display in the x direction, num_y
the number of pixels in the y direction, and (center_x,center_y)
the location of the center of the display; 

let scale_x = d/h*number_of_x_pixels, scale_y = d/v*number_of_y_pixels.

Then let S be defined as
__                           __
| scale_x center_x    0     0 |
|   0        1        0     0 |
|   0     center_y -scale_y 0 |
|   0        0        0     1 |
--                           --

Let the camera be located at (cx,cy,cz).  Let the vector E be pointing
in the direction the camera is facing, the vector D be pointing to
the right (along the camera's x axis), and the vector F be pointing
up (along the camera's z axis); and let D, E, and F be of length 1.
Then define the following matrices:

   matrix J        matrix C
| Dx Dy Dz 0 |  | 1 0 0 -cx |
| Ex Ey Ez 0 |  | 0 1 0 -cy |
| Fx Fy Fz 0 |  | 0 0 1 -cz |
| 0  0  0  1 |  | 0 0 0  1  |

and let N = S*J*C.


Let each object i be at location cix, ciy, ciz, and let the matrix
which holds the current rotation for that object be O(i).  To rotate
the object around the q axis by n degrees, let new O(i) = Rq(n) * O(i).
To rotate the object about *its* q axis, let new O(i) = O(i) * Rq(n)
(I think.  I haven't looked at this closely, so it's probably wrong).

Let Otemp(i) be O(i) with the rightmost column of zeros replaced by
cix, ciy, and ciz, or in other words, the product of Temp(i)*O(i) where
Temp(i) is
__         __
| 1 0 0 cix |
| 0 1 0 ciy |
| 0 0 1 ciz |
| 0 0 0  1  |
--         --

Now, for each object i let M = N * Otemp(i).

Now, for each point P in i, let V = M * P, that is:

	Vx = M[0,0]*Px + M[0,1]*Py + M[0,2]*Pz + M[0,3];
	Vy = M[1,0]*Px + M[1,1]*Py + M[1,2]*Pz + M[1,3];
	Vz = M[2,0]*Px + M[2,1]*Py + M[2,2]*Pz + M[2,3];

Then the pixel to plot to is:

	If Vy>0
		(Vx/Vy, Vz/Vy)

Done.

-- 2 --

3D graphics: using matrices and vectors		Part 2

-  Allows you to independently rotate objects and move the camera
	 anywhere.
-  Does not discuss clipping.
-  Algorithm uses 16 multiplies, 2 divides, and 12 adds for each point,
   plus overhead per independently located object.  Also shows how some
   of the calculations are wasted, and reduces it to 9 multiplies and 9
   additions.


The folowomg is a derivation of some of the math for using 3D
graphics with matrices and vectors.  I don't see any way of
explaining how to use the matrix formulas without all the extra
context, so you'll have to wade through it.  In general, you can
simplify things by multiplying out the matrices and similar
techniques.

You have a world described by three dimensional coordinates--it
could be lines or points or polygons, whatever.  You have an
imaginary camera in this world, and you want to draw exactly
what this camera would see.

We represent the camera as a point where an "eye" is and a window
through which it's looking--that is, a point for the eye, a vector
from the eye to the center of the window, and another vector to tell
us which way is the up direction on the window.  We can figure out
the sideways direction of the window by taking a cross-product, but
it may be better to represent it explicitly, as discussed far
eventually below.

What we want to know is where on our screen we should plot a
particular point.  The solution is to figure out where on the
imaginary window the point would appear to be, and then to map
the window onto our screen.

Suppose the eye is at the origin, facing along the X axis, and
the point is in the XY plane so we can only look at two dimensions
for illustration purposes.

Y axis
 |                ___---
 |          ___---
 |    ___--- |           Point
 | ---       |
eye----------+------------------  X axis
   ---___    |
         ---_|_
        window ---___
                     ---___

Suppose the window ranges from (d,h/2) to (d,-h/2) and the point is at
(a,b).  We want to know where the line from the point to the eye
intersects the window line.  Well, the point is only visible if
it's in front of the eye, so assume a>0.  Now, the two lines are

	y = (b/a)*x		(from Point to eye)
and	x = d			(line window is on)

So the location of intersection is (d,(b/a)*d).  In other words,
the point appears on our imaginary window with horizontal position
d*b/a if |d*b/a| <= h/2.

Thus, the quick and dirty 3d graphics formula for assuming an eyepoint
at the origin, X horizontal, positive to the right, Y vertical, positive
up, and Z depth, positive going into the distance (this is a left-handed
universe, whereas the rest of the derivations will be for a right handed
universe), and screen coordinates sx horizontal, positive to the right
sy vertical, positive down, is:

	if (Z>0) then
		sx = x_scale * X / Z + x_center;
		sy = - y_scale * Y / Z + y_center;
	endif

where x_center, y_center is the pixel address of the center of the
screen; x_scale is d/h*number_of_pixels_horizontally and y_scale is
d/v*number_of_pixels_vertically; d is the distance between the eye
and the window in the imaginary camera, h and v are the height and
width respectively of the imaginary window.

Ok, back to the messy stuff.  Since our eyepoint won't necessarily
be at the origin and facing in the right direction, we need to be
able to handle arbitrary translations and rotations.  In general,
to rotate (a,b) into (a',b') based on a given angle t, we do

	a' = cos(t)*a + sin(t)*b;
	b' = cos(t)*b - sin(t)*a;
(or switch the signs depending on which way you want to define as
the positive direction of rotation).

Now, to cleanly handle multiple rotations, we want to use matrices
to handle this.  This is the same as

	| cos(t) sin(t)|  |a| _ |a'|
	|-sin(t) cos(t)|  |b| - |b'|

that is, a 2x2 matrix times a 2x1 matrix gives a 2x1 matrix.  Now
to handle an arbitrary 3D rotation, we need to rotate on any axis:

   rotate about x	   rotate about y	   rotate about z

| 1    0      0    |	| cos(t) 0 -sin(t) |	|  cos(t) sin(t) 0 |
| 0  cos(t) sin(t) |	|    0   1   0     |	| -sin(t) cos(t) 0 |
| 0 -sin(t) cos(t) |	| sin(t) 0  cos(t) |	|    0	    0    1 |

Now, to rotate about a particular point, we have to translate to that
point.  Say we want to rotate about (d,e,f).  Then we subtract (d,e,f)
from our point, rotate, and then add (d,e,f) again.  It would be nice
if we could do that automatically with the matrices, and there is a way
to, a cute trick.  We switch from 3x3 matrices to 4x4 matrices, and use
4-vectors.  For the rotation matrices, the new elements are all zero,
except the bottom right one which is 1; for example:

|  cos(t) sin(t) 0 0 |
| -sin(t) cos(t) 0 0 |
|    0      0    1 0 |
|    0      0    0 1 |

Also, all of our vectors have a fourth element, which is always 1.
(In programming this, you can just continue to use three-vectors and
program the 'multiply matrix by vector routine' to pretend there's
one there.)  Now, to do a translation we want:

	x' = x + k1;
	y' = y + k2;
	z' = z + k3;

It turns out that this does the trick:

| 1 0 0 k1 |  | x |
| 0 1 0 k2 |  | y |
| 0 0 1 k3 |  | z |
| 0 0 0 1  |  | 1 |


Now, let's define some matrix terms so we can compress our notation.
Let Rx(t), Ry(t), and Rz(t) be the 4x4 rotation matrices, and let
T(k1,k2,k3) signify the appropriate matrix as above.  To rotate a point
(a,b,c) theta around the y axis at point (d,e,f), we do the following
in sequence: T(-d,-e,-f), Ry(theta), T(d,e,f).  Now, one nice thing
about matrices is that we can get the effect of sequential application
by multiplying matrices; that is, if U = (a,b,c,1) and V=(a',b',c',1),
then do  T(-d,-e,-f)*U, and take that and do Ry(theta)*that, and take
this and do T(d,e,f)*this, giving V, then this is:

	T(d,e,f) * ( Ry(theta) * ( T(-d,-e,-f) * U ) ) ) = V

Since matrix operations are associative, this is the same as

	T(d,e,f) * Ry(theta) * T(-d,-e,-f) * U = V

or, in other words, let M = T(d,e,f)*Ry(theta)*T(-d,-e,-f), then
M is a matrix which performs the rotation we desire.

Ok, now to wrap it all up.  Suppose we have a bunch of objects in
3D we want to display, and the aforementioned camera.  The camera
is at (cx,cy,cz), and we have a vector E pointing in the direction
the camera is aiming, a vector D which shows which way the window
is pointing to the right, and a vector F which points along the window
upward.  These vectors form an orthonormal basis, so to rotate into
the frame of reference for them we use the matrix

| Dx Dy Dz |
| Ex Ey Ez |
| Fx Fy Fz |

also, we want to use 4x4 matrices and first we want to translate
to cx..cz, so we use

   matrix J        matrix C
| Dx Dy Dz 0 |  | 0 0 0 -cx |
| Ex Ey Ez 0 |  | 0 0 0 -cy |
| Fx Fy Fz 0 |  | 0 0 0 -cz |
| 0  0  0  1 |  | 0 0 0  1  |

So for an arbitrary point (a,b,c) in three space, the screen coordinates
for it sx, sy are:  let U = (a,b,c,1); let V = J*C*U.  Then

	if (Vy>0) then
		sx = scale_x * Vx/Vy + center_x;
		sy = - scale_y * Vz/Vy + center_y;
	endif

Generally, we want to store J and C separately.  It is pretty simple
to move the camera, now; if the camera is always moving in the direction
its facing, use the E vector and factor direction in by hand, and
put this into C.  To rotate the camera, just multiply a rotation
matrix on the left by J.

Now, to rotate objects properly, keep a separate rotation matrix
for each object.  Then for each point in that object, rotate it and
translate it.  It's simplest to store each object with the origin
as the center of the object.  Then to calculate a point, you multiply
by the rotation matrix and then by the translation to put the objects
center where it should be in world space; because you're doing the
translation second, it's easy to put it into one matrix:

translation    rotation
| 1 0 0 l |   | a b c 0 |   | a b c l |
| 0 1 0 m |   | d e f 0 | _ | d e f m |
| 0 0 1 n | * | g h i 0 | - | g h i n |
| 0 0 0 1 |   | 0 0 0 1 |   | 0 0 0 1 |

Call this matrix O(q) where q is the object number.

Then, for each point in object q, the final multiply is
V = J * C * O(q) * U.

Finally, we can move some of the final calculation into a matrix.
We have:
	sx = scale_x * Vx/Vy + center_x;
	sy = -scale_y * Vz/Vy + center_y;

If we factor out Vy, we get
	sx = (scale_x * Vx + center_x * Vy)/Vy;
	sy = (-scale_y * Vz + center_y * Vy)/Vy;

Suppose from V we calculate V':
	(scale_x*Vx + center_x*Vy, Vy, -scale_y*Vz + center_y*Vz, 1)

Then
	sx = V'x / V'y;
	sy = V'z / V'y;

Well, to get V', we just multiply V by the matrix

| scale_x center_x    0     0 |
|   0        1        0     0 |
|   0     center_y -scale_y 0 |
|   0        0        0     1 |

Let us call this matrix S.  Remember, scale_x = d/h*number_of_x_pixels,
scale_y = d/v*number_of_y_pixels, d is distance from eye to window,
h is width of imaginary screen, v is height of imaginary screen.

So, now, the basic idea is this.  To minimize calculation, let 
N = S * J * C.  For each object q, let M = N * O(q).  For every point
U in q, let V = M * U.  If Vy>0, then that point is at (Vx/Vy,Vz/Vy)
on the screen.

In pseudo-code, that's

/* matrix_multiply (destination, left_multiplicand, right_multiplicand) */

for each time slice do
	if camera has moved then
		matrix_multiply ( N, J, C);
		matrix_multiply ( N, S, N);
	endif

	for q an object do
		matrix_multiply( M, N, O[q]);
		for p a point in object q do
			matrix_by_vector_multiply( V, M, U[q][p]);
			do something with  ( V[0]/V[1], V[2]/V[1] );
		endfor
	endfor
endfor

In truth, the matrix_by_vector_multiply wastes a bit of time, if you're
trying to tune the code, it'd be worth tuning it.  Normally, it does
this:

V0 = M00*U0 + M01*U1 + M02*U2 + M03*U3;
V1 = M10*U0 + M11*U1 + M12*U2 + M13*U3;
V2 = M20*U0 + M21*U1 + M22*U2 + M23*U3;
V3 = M30*U0 + M31*U1 + M32*U2 + M33*U3;

However, we know that the bottom row is never used, since V3 is always
1; furthermore, we know that U3 is 1, so we can just do

V0 = M00*U0 + M01*U1 + M02*U2 + M03;
V1 = M10*U0 + M11*U1 + M12*U2 + M13;
V2 = M20*U0 + M21*U1 + M22*U2 + M23;

This uses nine multiplies and nine adds, plus the two divides required
to calculate the screen coordinate.  I believe this is the minimum
possible for arbitrary 3D graphics.  (You can turn the two divides into
one divide and two multiplies by calculating 1/Vy and multiplying by
that, which may be a win on some machines.)




