@DATABASE "Screens"
@AUTHOR   "Paul Manias"
@NODE     "Main" "Screens Documentation"

@{b}@{u}MODULE DOCUMENTATION@{uu}@{ub}
Name:      @{"SCREENS" LINK "Functions"}
Version:   0.9 Beta
Date:      December 1997
Author:    Paul Manias
Copyright: DreamWorld Productions, 1996-1997.  All rights reserved.
Notes:     This  document is still being written and will contain errors
           in  a  number  of  places.   The information within cannot be
           treated as official until this autodoc reaches version 1.0.

@{b}@{u}CHANGES VERSION 0.9B@{uu}@{ub}
Added:   WaitSwitch()
         LockVideo()
         UnlockVideo()
         Display Buffering
         Video Locking

Renamed: MovePicture() to MoveBitmap()
         ResetPicture() to ResetBitmap()

Edited:  MoveBitmap()

Deleted: Removed all Sprite references and functions.  Sprites will not
         appear in V1.0.

         All of the raster functions have been removed, as there is now
         an OO Raster object.

@EndNode
---------------------------------------------------------------------------
@NODE "Functions" "Module: Screens"

 @{"INTRODUCTION" LINK "Introduction"}

 @{b}OBJECTS@{ub}
 @{"Raster" LINK "GMSDev:AutoDocs/Objects/Raster.guide/Description"}
 @{"Screen" LINK "GMSDev:AutoDocs/Objects/Screen.guide/Description"}

 @{b}THEORY@{ub}
 @{"Display Buffering" LINK "DisplayBuffering"}
 @{"Video Locking"     LINK "VideoLocking"}

 @{b}FUNCTIONS@{ub}
 @{"AllocVideoMem()" LINK "AllocVideoMem()"}
 @{"BlankOn()"       LINK "BlankOn()"}
 @{"BlankOff()"      LINK "BlankOff()"}
 @{"FreeVideoMem()"  LINK "FreeVideoMem()"}
 @{"GetScrType()"    LINK "GetScrType()"}
 @{"HideDisplay()"   LINK "HideDisplay()"}
 @{"LockVideo()"     LINK "LockVideo()"}
 @{"MoveBitmap()"    LINK "MoveBitmap()"}
 @{"ResetBitmap()"   LINK "ResetBitmap()"}
 @{"ReturnDisplay()" LINK "ReturnDisplay()"}
 @{"SwapBuffers()"   LINK "SwapBuffers()"}
 @{"TakeDisplay()"   LINK "TakeDisplay()"}
 @{"UnlockVideo()"   LINK "UnlockVideo()"}
 @{"WaitSwitch()"    LINK "WaitSwitch()"}
 @{"WaitAVBL()"      LINK "WaitAVBL()"}
 @{"WaitVBL()"       LINK "WaitVBL()"}
 @{"WaitRastLine()"  LINK "WaitRastLine()"}

 @{b}Colour Functions@{ub}
 @{"BlankColours()"    LINK "BlankColours()"}
 @{"ChangeColours()"   LINK "ChangeColours()"}
 @{"ColourMorph()"     LINK "ColourMorph()"}
 @{"ColourToPalette()" LINK "ColourToPalette()"}
 @{"PaletteToColour()" LINK "PaletteToColour()"}
 @{"PaletteMorph()"    LINK "PaletteMorph()"}
 @{"UpdatePalette()"   LINK "UpdatePalette()"}
 @{"UpdateColour()"    LINK "UpdateColour()"}

@EndNode
---------------------------------------------------------------------------
@NODE "Introduction" "Screens Module Overview"
@{b}
                          SCREEN SUPPORT OVERVIEW
@{ub}

The  Screens  module  was  the first module to be designed, and speed was a
major  factor  while  it was being programmed.  To keep it fast, the Screen
object  has  been kept highly simplified while not giving away any powerful
features.  One example of this power is that you can move the screen around
by  changing  its  coordinates,  and  even  dynamically alter its width and
height  without  any  adverse  affect  on  the  picture  display  (see  the
Redimension demo).

There  exists  a wide range of functions, including special effects such as
proportional  fading,  which  allows  you  to  add  some  very  smooth  and
impressive  touches  to your programs.  The Raster support provides an easy
to  use  gateway  to the copper chip.  Using the available commands you can
acheive affects like mirrors and smooth gradients of colour.

The  Screens  module is further supported in GMSPrefs, allowing the user to
select  his  preferred  screen  modes.  A powerful feature is being able to
select  the  screen  type,  so you can change the display type from ILBM to
Chunky  for  example.   This can give you a great speed up if your hardware
allows  you  to  use  such  modes and if the game would benefit from such a
change (eg 3D vectors).  It is even possible to do things such as upgrading
a  game  to  hi-res interlaced, or running in different video modes such as
DBLPAL.

@EndNode
---------------------------------------------------------------------------
@NODE "DisplayBuffering" "Screens: Display Buffering"
@{b}
                             DISPLAY BUFFERING
@{ub}


Display  buffering  is an important issue when you want to double buffer or
triple  buffer a screen.  The technique prevents flickering when drawing to
the  screen,  and  in  the  case  of  triple buffering it will speed up the
program loop.

There  are  different ways to achieve display buffering, I will explain two
of them:

@{u}Waiting Method@{uu}
This  method  is  used  for  double  buffering  and  some  cases  of triple
buffering.  It involves waiting for the vertical blank after you have drawn
your  data,  then  calling SwapBuffers().  This will usually look something
like this:

  while (loop) {
     Move(Bob);             /* Move objects */
     Draw(Bob);             /* Draw objects to bitmap */
     WaitVBL();             /* Wait for a vertical blank */
     SwapBuffers(Screen);   /* Swap the display buffers */
  }

You can see some real examples of this in the various demo source code.

@{u}Triple Buffering Method@{uu}
This  method  can  also  be  used  for  double  buffering,  but is provided
specifically  for  triple  buffering.  When the screen module is loaded, it
installs  a  special  vertical blank interrupt that lies in the background.
This  interrupt looks at the current screen and checks the Switch field for
TRUE.   If  set,  the  interrupt  will  switch the screen buffers while the
program is running.

At  this  stage  it  is important to know what the MemPtrX fields mean when
triple buffering:

  MemPtr1 - On display.
  MemPtr2 - Waiting for display/VBL ready.
  MemPtr3 - Being drawn to.

What this allows us to do is draw to the MemPtr3 buffer while the interrupt
takes  care  of  switching  the  MemPtr2 buffer to the display.  Here is an
example:

  Display(Screen);                      /* Display screen */

  Screen->Bitmap->Data = Screen->MemPtr2;

  while (loop) {

     /* This section will draw to the buffer in Bitmap->Data.  Because a
     ** switch will probably happen in this area you can understand why
     ** you are not allowed to read from the MemPtrX fields in such an
     ** "unsafe" area.
     */

     Move(Bob);
     Draw(Bob);

     /* At this point we have to make sure that the display has been
     ** switched.  If this is the case then we are running too fast and
     ** will have to wait until a buffer becomes ready.
     */

     WaitSwitch(Screen);                     /* Wait for switch to turn FALSE */
     Screen->Bitmap->Data = Screen->MemPtr3; /* Update for drawing */
     Screen->Switch = TRUE;                  /* We are ready to switch again */
  }

@EndNode
---------------------------------------------------------------------------
@NODE "VideoLocking" "Screens: Video Locking"

                               VIDEO LOCKING


@EndNode
---------------------------------------------------------------------------
@NODE "AllocVideoMem()" "Screens: AllocVideoMem()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     AllocVideoMem()
Short:    Allocate blitter memory.
Synopsis: APTR AllocVideoMem(LONG Size [d0], LONG Flags [d1])

@{b}@{u}DESCRIPTION@{uu}@{ub}
Allocates  a  block of memory suitable for the video display.  This type of
memory  is  also compatible with the blitter module, and should continue to
do so for all hardware configurations.

The  memory  will  be  tracked  as  outlined in AllocMemBlock() if resource
tracking is turned on.

@{b}@{u}INPUTS@{uu}@{ub}
Size  - The Size of the memory to allocate.
Flags - Memory flags as outlined in FreeMemBlock().

@{b}@{u}RESULT@{uu}@{ub}
Pointer  to  the  allocated memory.  All video memory is formatted with 0's
when allocated.  Returns NULL if error.

@{b}@{u}SEE ALSO@{uu}@{ub}
Kernel:  @{"FreeMemBlock()" LINK "GMSDev:AutoDocs/Kernel.guide/FreeMemBlock()"}
Screens: @{"FreeVideoMem()" LINK "FreeVideoMem()"}

@EndNode
---------------------------------------------------------------------------
@NODE "BlankColours()" "Screens: BlankColours()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     BlankColours()
Short:    Drives all screen colours to zero (black).
Synopsis: void BlankColours(*Screen [a0])

@{b}@{u}DESCRIPTION@{uu}@{ub}
Drives all the colours in a screen palette to zero, which will give a black
screen  (but  only  if  the ScrType makes use of the palette register).  If
successul,  you  won't be able to see any picture detail after calling this
routine.

@{b}@{u}INPUTS@{uu}@{ub}
Screen - Pointer to an initialised Screen structure.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"BlankOn()" LINK "BlankOn()"}

@EndNode
---------------------------------------------------------------------------
@NODE "BlankOn()" "Screens: BlankOn()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     BlankOn()
Short:    Blanks out the entire display until BlankOff() is called.
Synopsis: void BlankOn(void)

@{b}@{u}DESCRIPTION@{uu}@{ub}
After  calling  this function the screen display will be completely blanked
out  until  BlankOff()  is  called.   For  the duration that the display is
blanked out, there will be no visible screen effects whatsoever.  Note that
Display(Screen) is completely incapable of ending a screen blanking period,
but  once  the  screen  display  is returned any screen alterations will be
visible.

This  function  is  intended  for  making  a  clean  transition between two
screens, ie closing one screen then opening another.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"BlankOff()" LINK "BlankOff()"}

@EndNode
---------------------------------------------------------------------------
@NODE "BlankOff()" "Screens: BlankOff()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     BlankOff()
Short:    Gives back the display after BlankOn() was called.
Synopsis: void BlankOff(void)

@{b}@{u}DESCRIPTION@{uu}@{ub}
This  function  returns  the  screen  display after calling BlankOn().  Any
hidden  visual  changes  that occurred after the BlankOn() call will become
immediately visible after calling this function.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"BlankOn()" LINK "BlankOn()"}

@EndNode
----------------------------------------- ----------------------------------
@NODE "ColourMorph()" "Screens: ColourMorph()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     ColourMorph()
Short:    Fades a of set of colours into one colour value.
Synopsis: WORD ColourMorph(*Screen [a0], WORD FadeState [d0],
            WORD Speed [d1], LONG StartColour [d3], LONG AmtColours [d4],
            LONG SrcColour [d2], LONG DestColour [d5])

@{b}@{u}DESCRIPTION@{uu}@{ub}
Fades  the  screen from one colour into another colour.  Once you call this
function,  you  have  to  keep on calling it until it gives you a result of
NULL.   This  allows you to put this function in a loop and do other things
while the fade is active.

This function uses the proportional fading algorithm to acheive its effect.

@{b}@{u}NOTE@{uu}@{ub}
All  fading  functions  ignore  the colour values that are kept internally.
This  will  cause  problems  for  you  if you do not know what your current
palette looks like when using these functions.

@{b}@{u}EXAMPLE@{uu}@{ub}

    FadeState = NULL;
    do {
       WaitVBL();
       FadeState = ColourMorph(Screen,FadeState,1,0,32,0xFF00AA,0xA7BC30);
    }
    while (FadeState != NULL)

@{b}@{u}INPUTS@{uu}@{ub}
Screen      - Pointer to an initialised Screen structure.
FadeState   - Initialise  to  zero,  then keep sending the returned value
	      back until you get a NULL in this field.
Speed	    - The required speed for the fade.
SrcColour   - The colour that you are fading from, 0xRRGGBB format.
DestColour  - The colour that you are fading to, 0xRRGGBB format.
StartColour - The colour to start fading from (0 ... AmtColours-1).
AmtColours  - The amount of colours to fade (1 ... MaximumColours).  You
	      must never use a value of 0 here.

@{b}@{u}RESULT@{uu}@{ub}
Returns NULL if the fade has finished.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"ColourToPalette()" LINK "ColourToPalette()"}
         @{"PaletteMorph()"    LINK "PaletteMorph()"}
         @{"PaletteToColour()" LINK "PaletteToColour()"}

@EndNode
---------------------------------------------------------------------------
@NODE "ColourToPalette()" "Screens: ColourToPalette()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:      ColourToPalette()
Short:     Fades a set of colours into a range of values.
Synopsis:  WORD ColourToPalette(*Screen [a0], WORD FadeState [d0],
	    WORD Speed [d1], WORD StartColour [d3], WORD AmtColours [d4],
            APTR Palette [a1], LONG Colour [d2])

@{b}@{u}DESCRIPTION@{uu}@{ub}
Fades a set of colours of the same value, into a range of colours specified
in  Palette.   Once  you call this function, you have to keep on calling it
until  it gives you a result of NULL.  This allows you to put this function
in a loop and do other things while the fade is active.

This function uses the proportional fading algorithm to acheive its effect.

@{b}@{u}NOTE@{uu}@{ub}
All  fading  functions  ignore  the colour values that are kept internally.
This  will  cause  problems  for  you  if you do not know what your current
palette  looks like when using these functions.  Keep track of your current
palette values to help you with functions like PaletteMorph().

@{b}@{u}INPUTS@{uu}@{ub}
Screen      - Pointer to an initialised Screen structure.
FadeState   - Initialise  to  zero,  then keep sending the returned value
	       back until you get a NULL in this field.
Speed	    - The required speed for the fade.
Palette     - Pointer to the palette used as the source.
Colour      - The colour that you are fading from, 0xRRGGBB format.
StartColour - The colour to start fading from (0 ... AmtColours-1).
AmtColours  - The amount of colours to fade (1 ... MaximumColours).  You
               must never use a value of 0 here.

@{b}@{u}RESULT@{uu}@{ub}
Returns NULL if the fade has finished.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"ColourMorph()"     LINK "ColourMorph()"}
         @{"ColourToPalette()" LINK "ColourToPalette()"}
         @{"PaletteMorph()"    LINK "PaletteMorph()"}

@EndNode
---------------------------------------------------------------------------
@NODE "ChangeColours()" "Screens/ChangeColours"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:      ChangeColours()
Short:     Change a set of colours in a Screen's internal palette.
Synopsis:  void ChangeColours(*Screen [a0], APTR Colours [a1],
            LONG StartColour [d0], LONG AmtColours [d1])

@{b}@{u}DESCRIPTION@{uu}@{ub}
Changes all colours within the set range.  Alterations will only be made to
the screen's internal palette.

@{b}@{u}INPUTS@{uu}@{ub}
Screen      - Pointer to an initialised Screen structure.
Colours     - Pointer to a list of 24 bit colours.
StartColour - The  first  colour to be affected by the change.  NB:  The
               first colour is defined as 0.
AmtColours  - The  amount  of colours to be affected by the change.  Must
               be at least 1.

@EndNode
---------------------------------------------------------------------------
@NODE "FreeVideoMem()" "Screens: FreeVideoMem()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     FreeVideoMem()
Short:    Frees a memory block allocated from FreeVideoMem().
Synopsis: void FreeVideoMem(APTR MemBlock [d0])

@{b}@{u}DESCRIPTION@{uu}@{ub}
Frees a memory block allocated from AllocVideoMem().

@{b}@{u}INPUT@{uu}@{ub}
MemBlock - The memory block to be freed.

@{b}@{u}SEE ALSO@{uu}@{ub}
Kernel:  @{"AllocMemBlock()" LINK "GMSDev:AutoDocs/Kernel.guide/AllocMemBlock()"}
Screens: @{"AllocVideoMem()" LINK "AllocVideoMem()"}

@EndNode
---------------------------------------------------------------------------
@NODE "GetScrType()" "Screens: GetScrType()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     GetScrType()
Short:    Gets the default/user screen type.
Synopsis: LONG GetScrType(void)

@{b}@{u}DESCRIPTION@{uu}@{ub}
Returns  the  screen  type that is being used as the default in the screens
module.  This function is often used by other modules, since the ScrType is
a common field in structures not initialised by the Screens module.

@{b}@{u}RESULT@{uu}@{ub}
The default screen type (eg PLANAR).

@EndNode
---------------------------------------------------------------------------
@NODE "HideDisplay()" "Screens: HideDisplay()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     HideDisplay()
Short:    Hides the entire display from view.
Synopsis: *Screen = HideDisplay(void)

@{b}@{u}DESCRIPTION@{uu}@{ub}
This function is private and is for internal use only.

This  function will hide the GMS display from view.  This will cause the OS
viewport to be returned, but GMS will still be running "in the background".
If GMS is not running on top of another OS then the GMS DeskTop screen will
be displayed and the calling task will be put to the back.

If  no  GMS  screens  are  on  display then this function does nothing, and
returns a NULL value.

@{b}@{u}RESULT@{uu}@{ub}
Pointer  to  the  structure  of  the  Screen  that  has been hidden by this
function.  Otherwise NULL if no Screen was active.

@{b}@{u}SEE ALSO@{uu}@{ub}
Kernel: @{"Display()" LINK "Display()"}

@EndNode
---------------------------------------------------------------------------
@NODE "LockVideo()" "Screens: LockVideo()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     LockVideo()
Short:    Locks a screen at the front for video operations.
Synopsis: void LockVideo(*Screen [a0])

@{b}@{u}DESCRIPTION@{uu}@{ub}
This  function  is  required  whenever  you  want to draw something to your
screen,  or if you want to use the MemPtrX fields.  Locking a screen is the
only way to guarantee that the MemPtrX fields are pointing to video memory.

Attempting  to  draw  to  an  unlocked  screen with CPU or blitter can have
disasterous results, so use this function as often as necessary.

Some  systems  will  grant  locks  immediately, which is valid for most UMA
computers  and  standard  Amigas.   Other systems using graphics cards will
usually not do this.  Your task will have to wait until enough video memory
is ready, which may be until another task drops a screen lock or until the
user moves you to the front of the display.

@{b}@{u}NOTE@{uu}@{ub}
To keep the system stable, screen locks will nest.

@{b}@{u}INPUT@{uu}@{ub}
Screen - Pointer to an initialised screen structure.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"UnlockVideo()" LINK "UnlockVideo()"}
Theory:  @{"Video Locking" LINK "VideoLocking"}

@EndNode
---------------------------------------------------------------------------
@NODE "MoveBitmap()" "Screens: MoveBitmap()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     MoveBitmap()
Short:    Moves the screen bitmap to specified X/Y values.
Synopsis: void MoveBitmap(*Screen [a0])

@{b}@{u}DESCRIPTION@{uu}@{ub}
This  routine  has  two  uses:   Moving  the  bitmap to any position on the
display, and for Hardware Scrolling.

It  will  take  the  values  from  BmpXOffset  and BmpYOffset in the Screen
structure and use them to set the new picture position.  This function will
execute at the same speed for all offset values.

You  must have set the HSCROLL bit for horizontal scrolling and the VSCROLL
bit  for  vertical  scrolling if you wish to use this function.  If you set
the  HBUFFER  flag  in  ScrAttrib  then  you  can also use this function to
legally  hardware-scroll  up  to  50 screens in either X direction.  Do not
draw graphics beyond these boundaries as you will damage the system.

@{b}NOTES@{ub}
If  the graphics hardware does not support hardware scrolling, this routine
will  probably  blit  the entire picture to the new position.  This is very
slow but is the only other option.

The  normal  execution  time  for  this  function on ECS/AGA is 2/3rds of a
single raster line on an A1200+Fast.

@{b}@{u}INPUT@{uu}@{ub}
Screen - Pointer to an initialised Screen structure.  The BmpXOffset and
         BmpYOffset values will be used to set the picture's new on-screen
         position.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"ResetBitmap()" LINK "ResetBitmap()"}

@EndNode
---------------------------------------------------------------------------
@NODE "PaletteMorph()" "Screens: PaletteMorph()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     PaletteMorph()
Short:    Fades a set of colours into a new set of values.
Synopsis: WORD PaletteMorph(*Screen [a0], WORD FadeState [d0],
           WORD Speed [d1], WORD StartColour [d3], WORD AmtColours [d4],
           LONG *SrcPalette [a1], APTR DestPalette [a2])

@{b}@{u}DESCRIPTION@{uu}@{ub}
This  function  will  take  the palette in SrcPalette, and use it to fade a
colour  set  into  the  palette  given  in DestPalette.  Once you call this
function,  you  have  to  keep on calling it until it gives you a result of
NULL.   This  allows you to put this function in a loop and do other things
while the fade is active.

This function uses the proportional fading algorithm to acheive its effect.

@{b}@{u}NOTE@{uu}@{ub}
All  fading  functions  ignore  the colour values that are kept internally.
This  will  cause  problems  for  you  if you do not know what your current
palette  looks  like  when  using  these  functions.   Keep  track  of your
palette's  values  and  point  to  them in SrcPalette if you find that this
problem is occurring for you.

@{b}@{u}INPUTS@{uu}@{ub}
Screen      - Pointer to an initialised Screen structure.
FadeState   - Initialise  to  zero,  then keep sending the returned value
	       back until you get a NULL in this field.
Speed	    - The required speed for the fade.
SrcPalette  - Pointer to the palette used as the source.
Destpalette - Pointer to the palette that you want to fade to.
StartColour - The colour to start fading from (0 ... AmtColours-1).
AmtColours  - The amount of colours to fade (1 ... MaximumColours).  You
	       must never use a value of 0 here.

@{b}@{u}RESULT@{uu}@{ub}
Returns NULL if the fade has finished.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"ColourMorph()"     LINK "ColourMorph()"}
         @{"ColourToPalette()" LINK "ColourToPalette()"}
         @{"PaletteToColour()" LINK "PaletteToColour()"}

@EndNode
---------------------------------------------------------------------------
@NODE "PaletteToColour()" "Screens: PaletteToColour()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:	  PaletteToColour()
Short:    Fades a set of colours into a specific colour value.
Synopsis: WORD PaletteToColour(*Screen [a0], WORD FadeState [d0],
	   WORD Speed [d1], LONG StartColour [d3], LONG AmtColours [d4],
           APTR Palette [a1], LONG Colour [d2])

@{b}@{u}DESCRIPTION@{uu}@{ub}
This function will fade a set of various colour values into a single colour
value.   This  is  useful for fading the screen to black for example.  Once
you call this function, you have to keep on calling it until it gives you a
result  of  NULL.   This  allows  you to put this function in a loop and do
other things while the fade is active.

This function uses the proportional fading algorithm to acheive its effect.

@{b}@{u}NOTE@{uu}@{ub}
All  fading  functions  ignore  the colour values that are kept internally.
This  will  cause  problems  for  you  if you do not know what your current
palette looks like when using these functions.

@{b}@{u}INPUTS@{uu}@{ub}
Screen      - Pointer to an initialised Screen structure.
FadeState   - Initialise  to  zero,  then keep sending the returned value
	       back until you get a NULL in this field.
Speed	    - The required speed for the fade.
Palette     - Pointer to the palette used as the source.
Colour	    - The colour you want to fade to, in 0xRRGGBB format.
StartColour - The colour to start fading from (0 ... AmtColours-1).
AmtColours  - The amount of colours to fade (1 ... MaximumColours).  You
	       must never use a value of 0 here.

@{b}@{u}RESULT@{uu}@{ub}
Returns NULL if the fade has finished.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"ColourMorph()"     LINK "ColourMorph()"}
         @{"PaletteMorph()"    LINK "PaletteMorph()"}
         @{"PaletteToColour()" LINK "PaletteToColour()"}

@EndNode
---------------------------------------------------------------------------
@NODE "RefreshScreen()" "Screens: RefreshScreen()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     RefreshScreen()
Short:    Updates the screen display.
Synopsis: void RefreshScreen(*Screen [a0]);

@{b}@{u}DESCRIPTION@{uu}@{ub}



@{b}@{u}INPUT@{uu}@{ub}
Screen - Pointer to an initialised Screen structure.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"WaitVBL()" LINK "WaitVBL()"}

@EndNode
---------------------------------------------------------------------------
@NODE "RemakeScreen()" "Screens: RemakeScreen()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:      RemakeScreen()
Short:     Remakes the screen display according to its size, width, and
            position on the monitor.
Synopsis:  void RemakeScreen(*Screen [a0])

@{b}@{u}DESCRIPTION@{uu}@{ub}
Remakes  the  Screen's  viewport  as quickly as possible.  If the Screen is
currently  hidden,  then  the  changes  will show up the next time you call
Display(Screen).

You cannot change the display mode, screen type or amount of screen colours
with this function.

@{b}@{u}INPUT@{uu}@{ub}
Screen - Pointer to an initialised Screen structure.

@EndNode
---------------------------------------------------------------------------
@NODE "ResetBitmap()" "Screens: ResetBitmap()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     ResetBitmap()
Short:    Resets the picture position to position 0X, 0Y.
Synopsis: void ResetBitmap(*Screen [a0])

@{b}@{u}DESCRIPTION@{uu}@{ub}
Resets the picture position to 0X, 0Y.  This method is faster than clearing
the PicXOffset and PicYOffset fields and then calling MoveBitmap().

@{b}@{u}INPUT@{uu}@{ub}
Screen - Pointer to an initialised Screen structure.

@{b}@{u}RESULT@{uu}@{ub}
PicXOffset and PicYOffset in the Screen will be cleared.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"MoveBitmap" LINK "MoveBitmap()"}

@EndNode
---------------------------------------------------------------------------
@NODE "ReturnDisplay()" "Screens: ReturnDisplay()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     ReturnDisplay()
Short:    Private function.
Synopsis: Screen = ReturnDisplay(void);

@{b}@{u}DESCRIPTION@{uu}@{ub}
This function is private and is for internal use only.

Returns  the  monitor  display to the OS that GMS is running on.  This is a
special  function  in  the  monitor drivers, and is reserved for use in the
screens module.

@{b}@{u}RESULT@{uu}@{ub}
Pointer to the Screen that was removed.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"TakeDisplay()" LINK "TakeDisplay()"}

@EndNode
---------------------------------------------------------------------------
@NODE "SwapBuffers()" "Screens: SwapBuffers()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     SwapBuffers()
Short:    Switch the screen display buffers.
Synopsis: void SwapBuffers(*Screen [a0])

@{b}@{u}DESCRIPTION@{uu}@{ub}
If  the screen is double buffered, this function swaps Screen->MemPtr1 with
Screen->MemPtr2,  and  activates the new bitmap for the display.  If triple
buffered, then all three MemPtr's are switched.  Visually:

	@{b}BEFORE          AFTER@{ub}
	MemPtr1         MemPtr2
	MemPtr2  ---->  MemPtr3
	MemPtr3         MemPtr1

@{b}@{u}INPUT@{uu}@{ub}
Screen - Pointer to an initialised Screen structure.

@{b}@{u}SEE ALSO@{uu}@{ub}
Theory: @{"Dislay Buffering" LINK "DisplayBuffering"}

@EndNode
---------------------------------------------------------------------------
@NODE "TakeDisplay()" "Screens: TakeDisplay()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     TakeDisplay()
Short:    Private function.
Synopsis: LONG TakeDisplay(*Screen [a0])

@{b}@{u}DESCRIPTION@{uu}@{ub}
Takes  the  display from the Operating System that GMS is running on.  This
is  a  special  function in the monitor drivers, and is reserved for use in
the screens module.

@{b}@{u}INPUTS@{uu}@{ub}
Screen - Pointer to an initialised Screen structure.

@{b}@{u}RESULT@{uu}@{ub}
Returns ERR_OK if successful.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"ReturnDisplay()" LINK "ReturnDisplay()"}

@EndNode
---------------------------------------------------------------------------
@NODE "UnlockVideo()" "Screens: UnlockVideo()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     UnlockVideo()
Short:    
Synopsis: void UnlockVideo(*Screen [a0])

@{b}@{u}DESCRIPTION@{uu}@{ub}






@{b}@{u}INPUTS@{uu}@{ub}
Screen - Pointer to an initialised Screen object.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"LockVideo()"   LINK "LockVideo()"}
Theory:  @{"Video Locking" LINK "VideoLocking"}

@EndNode
---------------------------------------------------------------------------
@NODE "UpdateColour()" "Screens: UpdateColour()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     UpdateColour()
Short:    Updates a 24 bit $RRGGBB value in a Screen palette.
Synopsis: void UpdateRGB(*Screen [a0], LONG Colour [d0], LONG RRGGBB [d1])

@{b}@{u}DESCRIPTION@{uu}@{ub}
Updates  a  single  colour  value  in  the screen's palette.  The change is
immediately visible following the next vertical blank.

@{b}@{u}INPUTS@{uu}@{ub}
Screen - Pointer to an initialised Screen object.
Colour - The colour number to update, between 0 and Screen->AmtColours.
RRGGBB - Colour value in standard RRGGBB format.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"UpdatePalette()" LINK "UpdatePalette()"}

@EndNode
---------------------------------------------------------------------------
@NODE "UpdatePalette()" "Screens: UpdatePalette()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     UpdatePalette()
Short:    Updates an entire Screen palette to new colour values.
Synopsis: void UpdatePalette(*Screen [a0])

@{b}@{u}DESCRIPTION@{uu}@{ub}
Updates an entire Screen palette to new colour values, as pointed to in
the  GS_Palette  field.   If  GS_Palette  is  NULL  then all of the screens
colours will be turned black.

This function has no effect on true colour screens.

@{b}@{u}NOTE@{uu}@{ub}
Palette changes will appear when the next vertical blank occurs.

@{b}@{u}INPUTS@{uu}@{ub}
Screen - Pointer to an initialised Screen structure.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"UpdateColour()" LINK "UpdateColour()"}

@EndNode
---------------------------------------------------------------------------
@NODE "WaitRastLine()" "Screens: WaitRastLine()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     WaitRastLine()
Short:    Waits for the strobe to reach a specific line.
Synopsis: void WaitRastLine(WORD LineNumber [d0])

@{b}@{u}DESCRIPTION@{uu}@{ub}
Waits  for  the strobe to reach the scan-line specified in LineNumber.  The
recognised  range is dependent on the low resolution height of your screen,
eg  0-255  for  a  standard  320x256  screen.   It  is permissable to enter
negative  values  and  values  that  exceed  this  range, but only do so if
absolutely necessary.

This function has been specially written to avoid beam misses caused by the
untimely activation of interrupts.

@{b}@{u}INPUTS@{uu}@{ub}
LineNumber - Vertical beam position to wait for.

@{b}@{u}BUGS@{uu}@{ub}
If  you enter a large value that is well beyond the range limit, like #350,
the  strobe will never reach this line because line 350 doesn't even exist.
Please keep your values restricted to the height of your screen.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"WaitVBL()" LINK "WaitVBL()"}

@EndNode
---------------------------------------------------------------------------
@NODE "WaitSwitch()" "Screens: WaitSwitch()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     WaitSwitch()
Short:    Wait for the buffers to be switched at the vertical blank.
Synopsis: void WaitSwitch(*Screen [a0])

@{b}@{u}DESCRIPTION@{uu}@{ub}



@{b}@{u}INPUT@{uu}@{ub}
Screen - Pointer to an initialised Screen object.

@{b}@{u}SEE ALSO@{uu}@{ub}
Theory: @{"Display Buffering" LINK "DisplayBuffering"}

@EndNode
---------------------------------------------------------------------------
@NODE "WaitAVBL()" "Screens: WaitAVBL()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     WaitAVBL()
Short:    Waits for a vertical blank.
Synopsis: LONG WaitAVBL(void)

@{b}@{u}DESCRIPTION@{uu}@{ub}
Waits  until  the  horizontal  beam  reaches the Vertical BLank area.  This
routine  will  try  and  give you as much VBL space as possible, usually by
waiting  for  the  exact  point  where  the  display stops.  If this is not
possible,  then  it  will wait for the beam to reach the top of the monitor
display.

This  version  of  WaitVBL() will automatically pause your task if the user
moves  the  focus to a different screen.  This can be exceptionally useful,
as it will prevent your program from stealing resources when the user wants
to do something else.

@{b}@{u}RESULT@{uu}@{ub}
Currently returns null.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"WaitRastLine()" LINK "WaitRastLine()"}

@EndNode
---------------------------------------------------------------------------
@NODE "WaitVBL()" "Screens: WaitVBL()"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     WaitVBL()
Short:    Waits for a vertical blank.
Synopsis: LONG WaitVBL(void)

@{b}@{u}DESCRIPTION@{uu}@{ub}
Waits  until  the  horizontal  beam  reaches the Vertical BLank area.  This
routine  will  try  and  give you as much VBL space as possible, usually by
waiting  for  the  exact  point  where  the  display stops.  If this is not
possible,  then  it  will wait for the beam to reach the top of the monitor
display.

@{b}@{u}RESULT@{uu}@{ub}
Currently returns null.

@{b}@{u}SEE ALSO@{uu}@{ub}
Screens: @{"WaitRastLine()" LINK "WaitRastLine()"}

@EndNode
---------------------------------------------------------------------------
@NODE "()" "Screens:"

@{b}@{u}FUNCTION@{uu}@{ub}
Name:     
Short:    
Synopsis: 

@{b}@{u}DESCRIPTION@{uu}@{ub}

@{b}@{u}INPUTS@{uu}@{ub}

@{b}@{u}RESULT@{uu}@{ub}

@{b}@{u}SEE ALSO@{uu}@{ub}

@EndNode
