mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-25 16:43:24 +02:00
699 lines
26 KiB
TeX
699 lines
26 KiB
TeX
%
|
|
% $Id$
|
|
% This file is part of the FPC documentation.
|
|
% Copyright (C) 1997, by Michael Van Canneyt
|
|
%
|
|
% The FPC documentation is free text; you can redistribute it and/or
|
|
% modify it under the terms of the GNU Library General Public License as
|
|
% published by the Free Software Foundation; either version 2 of the
|
|
% License, or (at your option) any later version.
|
|
%
|
|
% The FPC Documentation is distributed in the hope that it will be useful,
|
|
% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
% Library General Public License for more details.
|
|
%
|
|
% You should have received a copy of the GNU Library General Public
|
|
% License along with the FPC documentation; see the file COPYING.LIB. If not,
|
|
% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
% Boston, MA 02111-1307, USA.
|
|
%
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
%
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% The Video unit
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\chapter{The VIDEO unit}
|
|
\FPCexampledir{videoex}
|
|
|
|
The \file{Video} unit implements a screen access layer which is system
|
|
independent. It can be used to write on the screen in a system-independent
|
|
way, which should be optimal on all platforms for which the unit is
|
|
implemented.
|
|
|
|
The working of the \file{Video} is simple: After calling \seep{InitVideo},
|
|
the array \var{VideoBuf} contains a representation of the video screen of
|
|
size \var{ScreenWidth*ScreenHeight}, going from left to right and top to
|
|
bottom when walking the array elements: \var{VideoBuf[0]} contains the
|
|
character and color code of the top-left character on the screen.
|
|
\var{VideoBuf[ScreenWidth]} contains the data for the character in the
|
|
first column of the second row on the screen, and so on.
|
|
|
|
To write to the 'screen', the text to be written should be written to the
|
|
\var{VideoBuf} array. Calling \seep{UpdateScreen} will then cp the text to
|
|
the screen in the most optimal way. (an example can be found further on).
|
|
|
|
The color attribute is a combination of the foreground and background color,
|
|
plus the blink bit. The bits describe the various color combinations:
|
|
\begin{description}
|
|
\item[bits 0-3] The foreground color. Can be set using all color constants.
|
|
\item[bits 4-6] The background color. Can be set using a subset of the
|
|
color constants.
|
|
\item[bit 7] The blinking bit. If this bit is set, the character will appear
|
|
blinking.
|
|
\end{description}
|
|
Each possible color has a constant associated with it, see page
|
|
\pageref{vidcolorconst} for a list of constants.
|
|
|
|
The contents of the \var{VideoBuf} array may be modified: This is 'writing'
|
|
to the screen. As soon as everything that needs to be written in the array
|
|
is in the \var{VideoBuf} array, calling \var{UpdateScreen} will copy the
|
|
contents of the array screen to the screen, in a manner that is as efficient
|
|
as possible.
|
|
|
|
The updating of the screen can be prohibited to optimize performance; To
|
|
this end, the \seep{LockScreenUpdate} function can be used: This will
|
|
increment an internal counter. As long as the counter differs from zero,
|
|
calling \seep{UpdateScreen} will not do anything. The counter can be
|
|
lowered with \seep{UnlockScreenUpdate}. When it reaches zero, the next call
|
|
to \seep{UpdateScreen} will actually update the screen. This is useful when
|
|
having nested procedures that do a lot of screen writing.
|
|
|
|
The video unit also presents an interface for custom screen drivers, thus
|
|
it is possible to override the default screen driver with a custom screen
|
|
driver, see the \seef{SetVideoDriver} call. The current video driver can
|
|
be retrieved using the \seep{GetVideoDriver} call.
|
|
|
|
\begin{remark}
|
|
The video unit should {\em not} be used together with the \file{crt} unit.
|
|
Doing so will result in very strange behaviour, possibly program crashes.
|
|
\end{remark}
|
|
|
|
\section{Constants, Type and variables }
|
|
|
|
\subsection{Constants}
|
|
\label{vidcolorconst}
|
|
The following constants describe colors that can be used as
|
|
foreground and background colors.
|
|
\begin{verbatim}
|
|
Black = 0;
|
|
Blue = 1;
|
|
Green = 2;
|
|
Cyan = 3;
|
|
Red = 4;
|
|
Magenta = 5;
|
|
Brown = 6;
|
|
LightGray = 7;
|
|
\end{verbatim}
|
|
The following color constants can be used as foreground colors only:
|
|
\begin{verbatim}
|
|
DarkGray = 8;
|
|
LightBlue = 9;
|
|
LightGreen = 10;
|
|
LightCyan = 11;
|
|
LightRed = 12;
|
|
LightMagenta = 13;
|
|
Yellow = 14;
|
|
White = 15;
|
|
\end{verbatim}
|
|
The foreground and background color can be combined to a color attribute
|
|
with the following code:
|
|
\begin{verbatim}
|
|
Attr:=ForeGroundColor + (BackGroundColor shl 4);
|
|
\end{verbatim}
|
|
The color attribute can be logically or-ed with the blink attribute to
|
|
produce a blinking character:
|
|
\begin{verbatim}
|
|
Blink = 128;
|
|
\end{verbatim}
|
|
But not all drivers may support this.
|
|
|
|
The following constants describe the capabilities of a certain video mode:
|
|
\begin{verbatim}
|
|
cpUnderLine = $0001;
|
|
cpBlink = $0002;
|
|
cpColor = $0004;
|
|
cpChangeFont = $0008;
|
|
cpChangeMode = $0010;
|
|
cpChangeCursor = $0020;
|
|
\end{verbatim}
|
|
The following constants describe the various supported cursor modes:
|
|
\begin{verbatim}
|
|
crHidden = 0;
|
|
crUnderLine = 1;
|
|
crBlock = 2;
|
|
crHalfBlock = 3;
|
|
\end{verbatim}
|
|
When a video function needs to report an error condition, the following
|
|
constants are used:
|
|
\begin{verbatim}
|
|
vioOK = 0;
|
|
errVioBase = 1000;
|
|
errVioInit = errVioBase + 1; { Initialization error}
|
|
errVioNotSupported = errVioBase + 2; { Unsupported function }
|
|
errVioNoSuchMode = errVioBase + 3; { No such video mode }
|
|
\end{verbatim}
|
|
The following constants can be read to get some information about the
|
|
current screen:
|
|
\begin{verbatim}
|
|
ScreenWidth : Word = 0;
|
|
ScreenHeight : Word = 0;
|
|
LowAscii : Boolean = true;
|
|
NoExtendedFrame : Boolean = false;
|
|
FVMaxWidth = 132;
|
|
\end{verbatim}
|
|
The error-handling code uses the following constants:
|
|
\begin{verbatim}
|
|
errOk = 0;
|
|
ErrorCode: Longint = ErrOK;
|
|
ErrorInfo: Pointer = nil;
|
|
ErrorHandler: TErrorHandler = DefaultErrorHandler;
|
|
\end{verbatim}
|
|
The \var{ErrorHandler} variable can be set to a custom-error handling
|
|
function. It is set by default to the \seep{DefaultErrorHandler} function.
|
|
|
|
\subsection{Types}
|
|
The \var{TVideoMode} record describes a videomode. Its fields are
|
|
self-explaining: \var{Col,Row} describe the number of columns and
|
|
rows on the screen for this mode. \var{Color} is \var{True} if this mode
|
|
supports colors, or \var{False} if not.
|
|
\begin{verbatim}
|
|
PVideoMode = ^TVideoMode;
|
|
TVideoMode = record
|
|
Col,Row : Word;
|
|
Color : Boolean;
|
|
end;
|
|
\end{verbatim}
|
|
\var{TVideoCell} describes one character on the screen. The high byte
|
|
contains the color attribute with which the character is drawn on the screen,
|
|
and the low byte contains the ASCII code of the character to be drawn.
|
|
\begin{verbatim}
|
|
TVideoCell = Word;
|
|
PVideoCell = ^TVideoCell;
|
|
\end{verbatim}
|
|
The \var{TVideoBuf} and \var{PVideoBuf} are two types used to represent the
|
|
screen.
|
|
\begin{verbatim}
|
|
TVideoBuf = array[0..32759] of TVideoCell;
|
|
PVideoBuf = ^TVideoBuf;
|
|
\end{verbatim}
|
|
The following type is used when reporting error conditions:
|
|
\begin{verbatim}
|
|
TErrorHandlerReturnValue = (errRetry, errAbort, errContinue);
|
|
\end{verbatim}
|
|
Here, \var{errRetry} means retry the operation, \var{errAbort}
|
|
abort and return error code and \var{errContinue} means abort
|
|
without returning an errorcode.
|
|
|
|
The \var{TErrorHandler} function is used to register an own error
|
|
handling function. It should be used when installing a custom error
|
|
handling function, and must return one of the above values.
|
|
\begin{verbatim}
|
|
TErrorHandler =
|
|
function (Code: Longint; Info: Pointer): TErrorHandlerReturnValue;
|
|
\end{verbatim}
|
|
\var{Code} should contain the error code for the error condition,
|
|
and the \var{Info} parameter may contain any data type specific to
|
|
the error code passed to the function.
|
|
|
|
The \var{TVideoDriver} record can be used to install a custom video
|
|
driver, with the \seef{SetVideoDriver} call:
|
|
\begin{verbatim}
|
|
TVideoDriver = Record
|
|
InitDriver : Procedure;
|
|
DoneDriver : Procedure;
|
|
UpdateScreen : Procedure(Force : Boolean);
|
|
ClearScreen : Procedure;
|
|
SetVideoMode : Function (Const Mode : TVideoMode) : Boolean;
|
|
GetVideoModeCount : Function : Word;
|
|
GetVideoModeData : Function(Index : Word; Var Data : TVideoMode) : Boolean;
|
|
SetCursorPos : procedure (NewCursorX, NewCursorY: Word);
|
|
GetCursorType : function : Word;
|
|
SetCursorType : procedure (NewType: Word);
|
|
GetCapabilities : Function : Word;
|
|
end;
|
|
\end{verbatim}
|
|
|
|
\subsection{Variables}
|
|
The following variables contain information about the current screen
|
|
status:
|
|
\begin{verbatim}
|
|
ScreenColor : Boolean;
|
|
CursorX, CursorY : Word;
|
|
\end{verbatim}
|
|
\var{ScreenColor} indicates whether the current screen supports colors.
|
|
\var{CursorX,CursorY} contain the current cursor position.
|
|
|
|
The following variables form the heart of the \file{Video} unit: The
|
|
\var{VideoBuf} array represents the physical screen. Writing to this
|
|
array and calling \seep{UpdateScreen} will write the actual characters
|
|
to the screen. \var{VideoBufSize} contains the actual screen size, and is
|
|
equal to the product of the number of columns times the number of lines
|
|
on the screen (\var{ScreenWidth*ScreenHeight}).
|
|
\begin{verbatim}
|
|
VideoBuf : PVideoBuf;
|
|
OldVideoBuf : PVideoBuf;
|
|
VideoBufSize : Longint;
|
|
\end{verbatim}
|
|
The \var{OldVideoBuf} contains the state of the video screen after the last
|
|
screen update. The \seep{UpdateScreen} function uses this array to decide
|
|
which characters on screen should be updated, and which not.
|
|
|
|
Note that the \var{OldVideoBuf} array may be ignored by some drivers, so
|
|
it should not be used. The Array is in the interface section of the video
|
|
unit mainly so drivers that need it can make use of it.
|
|
|
|
\section{Functions and Procedures}
|
|
|
|
The examples in this section make use of the unit \file{vidutil}, which
|
|
contains the \var{TextOut} function. This function writes a text to the
|
|
screen at a given location. It looks as follows:
|
|
|
|
\FPCexample{vidutil}
|
|
|
|
\begin{procedure}{ClearScreen}
|
|
\Declaration
|
|
procedure ClearScreen;
|
|
\Description
|
|
\var{ClearScreen} clears the entire screen, and calls \seep{UpdateScreen}
|
|
after that. This is done by writing spaces to all character cells of the
|
|
video buffer in the default color (lightgray on black, color attribute \$07).
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{InitVideo}, \seep{UpdateScreen}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex3}
|
|
|
|
\begin{procedure}{DefaultErrorHandler}
|
|
\Declaration
|
|
function DefaultErrorHandler(AErrorCode: Longint; AErrorInfo: Pointer): TErrorHandlerReturnValue;
|
|
\Description
|
|
\var{DefaultErrorHandler} is the default error handler used by the video
|
|
driver. It simply sets the error code \var{AErrorCode} and \var{AErrorInfo}
|
|
in the global variables \var{ErrorCode} and \var{ErrorInfo} and returns
|
|
\var{errContinue}.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\end{procedure}
|
|
|
|
\begin{procedure}{DoneVideo}
|
|
\Declaration
|
|
procedure DoneVideo;
|
|
\Description
|
|
\var{DoneVideo} disables the Video driver if the video driver is active. If
|
|
the videodriver was already disabled or not yet initialized, it does
|
|
nothing. Disabling the driver means it will clean up any allocated
|
|
resources, possibly restore the screen in the state it was before
|
|
\var{InitVideo} was called. Particularly, the \var{VideoBuf} and
|
|
\var{OldVideoBuf} arrays are no longer valid after a call to
|
|
\var{DoneVideo}.
|
|
|
|
The \var{DoneVideo} should always be called if \var{InitVideo} was called.
|
|
Failing to do so may leave the screen in an unusable state after the program
|
|
exits.
|
|
\Errors
|
|
Normally none. If the driver reports an error, this is done through the
|
|
\var{ErrorCode} variable.
|
|
\SeeAlso
|
|
\seep{InitVideo}
|
|
\end{procedure}
|
|
|
|
For an example, see most other functions.
|
|
|
|
\begin{function}{GetCapabilities}
|
|
\Declaration
|
|
function GetCapabilities: Word;
|
|
\Description
|
|
\var{GetCapabilities} returns the capabilities of the current driver.
|
|
It is an or-ed combination of the following constants:
|
|
\begin{description}
|
|
\item[cpUnderLine] The driver supports underlined characters.
|
|
\item[cpBlink] The driver supports blinking characters.
|
|
\item[cpColor] The driver supports colors.
|
|
\item[cpChangeFont] The driver supports the setting of a screen font.
|
|
Note, however, that a font setting API is not supported by the video unit.
|
|
\item[cpChangeMode] The driver supports the setting of screen modes.
|
|
\item[cpChangeCursor] The driver supports changing the cursor shape.
|
|
\end{description}
|
|
Note that the video driver should not yet be initialized to use this
|
|
function. It is a property of the driver.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{GetCursorType}, \seep{GetVideoDriver}
|
|
\end{function}
|
|
|
|
\FPCexample{ex4}
|
|
|
|
\begin{function}{GetCursorType}
|
|
\Declaration
|
|
function GetCursorType: Word;
|
|
\Description
|
|
\var{GetCursorType} returns the current cursor type. It is one of the
|
|
following values:
|
|
\begin{description}
|
|
\item[crHidden] The cursor is currently hidden.
|
|
\item[crUnderLine] The cursor is currently the underline character.
|
|
\item[crBlock] The cursor is currently the block character.
|
|
\item[crHalfBlock] The cursur is currently a block with height of half the
|
|
character cell height.
|
|
\end{description}
|
|
Note that not all drivers support all types of cursors.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{SetCursorType}, \seef{GetCapabilities}
|
|
\end{function}
|
|
|
|
\FPCexample{ex5}
|
|
|
|
\begin{function}{GetLockScreenCount}
|
|
\Declaration
|
|
Function GetLockScreenCount : integer;
|
|
\Description
|
|
\var{GetLockScreenCount} returns the current lock level. When the lock
|
|
level is zero, a call to \seep{UpdateScreen} will actually update the
|
|
screen.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{LockScreenUpdate}, \seep{UnlockScreenUpdate}, \seep{UpdateScreen}
|
|
\end{function}
|
|
|
|
\FPCexample{ex6}
|
|
|
|
\begin{procedure}{GetVideoDriver}
|
|
\Declaration
|
|
Procedure GetVideoDriver (Var Driver : TVideoDriver);
|
|
\Declaration
|
|
\var{GetVideoDriver} retrieves the current videodriver and returns it in
|
|
\var{Driver}. This can be used to chain video drivers.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{SetVideoDriver}
|
|
\end{procedure}
|
|
|
|
For an example, see the section on writing a custom video driver.
|
|
|
|
\begin{procedure}{GetVideoMode}
|
|
\Declaration
|
|
procedure GetVideoMode(var Mode: TVideoMode);
|
|
\Description
|
|
\var{GetVideoMode} returns the settings of the currently active video mode.
|
|
The \var{row,col} fields indicate the dimensions of the current video mode,
|
|
and \var{Color} is true if the current video supports colors.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{SetVideoMode}, \seef{GetVideoModeData}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex7}
|
|
|
|
\begin{function}{GetVideoModeCount}
|
|
\Declaration
|
|
Function GetVideoModeCount : Word;
|
|
\Description
|
|
\var{GetVideoModeCount} returns the number of video modes that the current
|
|
driver supports. If the driver does not support switching of modes, then 1
|
|
is returned.
|
|
|
|
This function can be used in conjunction with the \seef{GetVideoModeData}
|
|
function to retrieve data for the supported video modes.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{GetVideoModeData}, \seep{GetVideoMode}
|
|
\end{function}
|
|
|
|
\FPCexample{ex8}
|
|
|
|
\begin{function}{GetVideoModeData}
|
|
\Declaration
|
|
Function GetVideoModeData(Index : Word; Var Data: TVideoMode) : Boolean;
|
|
\Description
|
|
\var{GetVideoModeData} returns the characteristics of the \var{Index}-th
|
|
video mode in \var{Data}. \var{Index} is zero based, and has a maximum value of
|
|
\var{GetVideoModeCount-1}. If the current driver does not support setting of
|
|
modes (\var{GetVideoModeCount=1}) and \var{Index} is zero, the current mode
|
|
is returned.
|
|
|
|
The function returns \var{True} if the mode data was retrieved succesfully,
|
|
\var{False} otherwise.
|
|
\Errors
|
|
In case \var{Index} has a wrong value, \var{False} is returned.
|
|
\SeeAlso
|
|
\seef{GetVideoModeCount}, \seef{SetVideoMode}, \seep{GetVideoMode}
|
|
\end{function}
|
|
|
|
For an example, see \seef{GetVideoModeCount}.
|
|
|
|
\begin{procedure}{InitVideo}
|
|
\Declaration
|
|
procedure InitVideo;
|
|
\Description
|
|
\var{InitVideo} Initializes the video subsystem. If the video system was
|
|
already initialized, it does nothing.
|
|
After the driver has been initialized, the \var{VideoBuf} and \var{OldVideoBuf}
|
|
pointers are initialized, based on the \var{ScreenWidth} and
|
|
\var{ScreenHeight} variables. When this is done, the screen is cleared.
|
|
\Errors
|
|
if the driver fails to initialize, the \var{ErrorCode} variable is set.
|
|
\SeeAlso
|
|
\seep{DoneVideo}
|
|
\end{procedure}
|
|
|
|
For an example, see most other functions.
|
|
|
|
\begin{procedure}{LockScreenUpdate}
|
|
\Declaration
|
|
Procedure LockScreenUpdate;
|
|
\Description
|
|
\var{LockScreenUpdate} increments the screen update lock count with one.
|
|
As long as the screen update lock count is not zero, \seep{UpdateScreen}
|
|
will not actually update the screen.
|
|
|
|
This function can be used to optimize screen updating: If a lot of writing
|
|
on the screen needs to be done (by possibly unknown functions), calling
|
|
\var{LockScreenUpdate} before the drawing, and \seep{UnlockScreenUpdate}
|
|
after the drawing, followed by a \seep{UpdateScreen} call, all writing will
|
|
be shown on screen at once.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{UpdateScreen}, \seep{UnlockScreenUpdate}, \seef{GetLockScreenCount}
|
|
\end{procedure}
|
|
|
|
For an example, see \seef{GetLockScreenCount}.
|
|
|
|
\begin{procedure}{SetCursorPos}
|
|
\Declaration
|
|
procedure SetCursorPos(NewCursorX, NewCursorY: Word);
|
|
\Description
|
|
\var{SetCursorPos} positions the cursor on the given position: Column
|
|
\var{NewCursorX} and row \var{NewCursorY}. The origin of the screen is the
|
|
upper left corner, and has coordinates \var{(0,0)}.
|
|
|
|
The current position is stored in the \var{CursorX} and \var{CursorY}
|
|
variables.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{SetCursorType}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex2}
|
|
|
|
\begin{procedure}{SetCursorType}
|
|
\Declaration
|
|
procedure SetCursorType(NewType: Word);
|
|
\Description
|
|
\var{SetCursorType} sets the cursor to the type specified in \var{NewType}.
|
|
\begin{description}
|
|
\item[crHidden] the cursor is not visible.
|
|
\item[crUnderLine] the cursor is a small underline character (usually
|
|
denoting insert mode).
|
|
\item[crBlock] the cursor is a block the size of a screen cell (usually
|
|
denoting overwrite mode).
|
|
\item[crHalfBlock] the cursor is a block half the size of a screen cell.
|
|
\end{description}
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{SetCursorPos}
|
|
\end{procedure}
|
|
|
|
\begin{function}{SetVideoDriver}
|
|
\Declaration
|
|
Function SetVideoDriver (Const Driver : TVideoDriver) : Boolean;
|
|
\Description
|
|
\var{SetVideoDriver} sets the videodriver to be used to \var{Driver}. If
|
|
the current videodriver is initialized (after a call to \var{InitVideo})
|
|
then it does nothing and returns \var{False}.
|
|
|
|
A new driver can only be installed if the previous driver was not yet
|
|
activated (i.e. before a call to \seep{InitVideo}) or after it was
|
|
deactivated (i.e after a call to \var{DoneVideo}).
|
|
|
|
For more information about installing a videodriver, see \sees{viddriver}.
|
|
\Errors
|
|
If the current driver is initialized, then \var{False} is returned.
|
|
\SeeAlso
|
|
The example video driver in \sees{viddriver}
|
|
\end{function}
|
|
|
|
For an example, see the section on writing a custom video driver.
|
|
|
|
\begin{function}{SetVideoMode}
|
|
\Declaration
|
|
Function SetVideoMode(Mode: TVideoMode) : Boolean;
|
|
\Description
|
|
\var{SetVideoMode} sets the video mode to the mode specified in \var{Mode}:
|
|
\begin{verbatim}
|
|
TVideoMode = record
|
|
Col,Row : Word;
|
|
Color : Boolean;
|
|
end;
|
|
\end{verbatim}
|
|
If the call was succesful, then the screen will have \var{Col} columns and
|
|
\var{Row} rows, and will be displaying in color if \var{Color} is
|
|
\var{True}.
|
|
|
|
The function returns \var{True} if the mode was set succesfully, \var{False}
|
|
otherwise.
|
|
|
|
Note that the video mode may not always be set. E.g. a console on Linux
|
|
or a telnet session cannot always set the mode. It is important to check
|
|
the error value returned by this function if it was not succesful.
|
|
|
|
The mode can be set when the video driver has not yet been initialized
|
|
(i.e. before \seep{InitVideo} was called) In that case, the video mode will
|
|
be stored, and after the driver was initialized, an attempt will be made to
|
|
set the requested mode. Changing the video driver before the call to
|
|
\var{InitVideo} will clear the stored video mode.
|
|
|
|
To know which modes are valid, use the \seef{GetVideoModeCount} and
|
|
\seef{GetVideoModeData} functions. To retrieve the current video mode,
|
|
use the \seep{GetVideoMode} procedure.
|
|
\Errors
|
|
If the specified mode cannot be set, then \var{errVioNoSuchMode} may be set
|
|
in \var{ErrorCode}
|
|
\SeeAlso
|
|
\seef{GetVideoModeCount}
|
|
\seef{GetVideoModeData}
|
|
\seep{GetVideoMode}
|
|
\end{function}
|
|
|
|
\begin{procedure}{UnlockScreenUpdate}
|
|
\Declaration
|
|
Procedure UnlockScreenUpdate;
|
|
\Description
|
|
\var{UnlockScreenUpdate} decrements the screen update lock count with one if
|
|
it is larger than zero. When the lock count reaches zero, the
|
|
\seep{UpdateScreen} will actually update the screen. No screen update will
|
|
be performed as long as the screen update lock count is nonzero. This
|
|
mechanism can be used to increase screen performance in case a lot of
|
|
writing is done.
|
|
|
|
It is important to make sure that each call to \seep{LockScreenUpdate} is
|
|
matched by exactly one call to \var{UnlockScreenUpdate}
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{LockScreenUpdate}, \seef{GetLockScreenCount}, \seep{UpdateScreen}
|
|
\end{procedure}
|
|
|
|
For an example, see \seef{GetLockScreenCount}.
|
|
|
|
\begin{procedure}{UpdateScreen}
|
|
\Declaration
|
|
procedure UpdateScreen(Force: Boolean);
|
|
\Description
|
|
\var{UpdateScreen} synchronizes the actual screen with the contents
|
|
of the \var{VideoBuf} internal buffer. The parameter \var{Force}
|
|
specifies whether the whole screen has to be redrawn (\var{Force=True})
|
|
or only parts that have changed since the last update of the screen.
|
|
|
|
The \var{Video} unit keeps an internal copy of the screen as it last
|
|
wrote it to the screen (in the \var{OldVideoBuf} array). The current
|
|
contents of \var{VideoBuf} are examined to see what locations on the
|
|
screen need to be updated. On slow terminals (e.g. a \linux telnet
|
|
session) this mechanism can speed up the screen redraw considerably.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{ClearScreen}
|
|
\end{procedure}
|
|
|
|
For an example, see most other functions.
|
|
|
|
\section{Writing a custom video driver}
|
|
\label{se:viddriver}
|
|
Writing a custom video driver is not difficult, and generally means
|
|
implementing a couple of functions, which whould be registered with
|
|
the \seef{SetVideoDriver} function. The various functions that can be
|
|
implemented are located in the \var{TVideoDriver} record:
|
|
\begin{verbatim}
|
|
TVideoDriver = Record
|
|
InitDriver : Procedure;
|
|
DoneDriver : Procedure;
|
|
UpdateScreen : Procedure(Force : Boolean);
|
|
ClearScreen : Procedure;
|
|
SetVideoMode : Function (Const Mode : TVideoMode) : Boolean;
|
|
GetVideoModeCount : Function : Word;
|
|
GetVideoModeData : Function(Index : Word; Var Data : TVideoMode) : Boolean;
|
|
SetCursorPos : procedure (NewCursorX, NewCursorY: Word);
|
|
GetCursorType : function : Word;
|
|
SetCursorType : procedure (NewType: Word);
|
|
GetCapabilities : Function : Word;
|
|
end;
|
|
\end{verbatim}
|
|
Not all of these functions must be implemented. In fact, the only absolutely
|
|
necessary function to write a functioning driver is the \var{UpdateScreen}
|
|
function. The general calls in the \file{Video} unit will check which
|
|
functionality is implemented by the driver.
|
|
|
|
The functionality of these calls is the same as the functionality of the
|
|
calls in the video unit, so the expected behaviour can be found in the
|
|
previous section. Some of the calls, however, need some additional remarks.
|
|
\begin{description}
|
|
\item[InitDriver] Called by \var{InitVideo}, this function should initialize
|
|
any data structures needed for the functionality of the driver, maybe do some
|
|
screen initializations. The function is guaranteed to be called only once; It
|
|
can only be called again after a call to \var{DoneVideo}. The variables
|
|
\var{ScreenWidth} and \var{ScreenHeight} should be initialized correctly
|
|
after a call to this function, as the \var{InitVideo} call will initialize
|
|
the \var{VideoBuf} and \var{OldVideoBuf} arrays based on their values.
|
|
\item[DoneDriver] This should clean up any structures that have been
|
|
initialized in the \var{InitDriver} function. It should possibly also
|
|
restore the screen as it was before the driver was initialized. The VideoBuf
|
|
and \var{OldVideoBuf} arrays will be disposed of by the general \var{DoneVideo}
|
|
call.
|
|
\item[UpdateScreen] This is the only required function of the driver. It
|
|
should update the screen based on the \var{VideoBuf} array's contents. It
|
|
can optimize this process by comparing the values with values in the
|
|
\var{OldVideoBuf} array. After updating the screen, the \var{UpdateScreen}
|
|
procedure should update the \var{OldVideoBuf} by itself. If the \var{Force}
|
|
parameter is \var{True}, the whole screen should be updated, not just the
|
|
changed values.
|
|
\item[ClearScreen] If there is a faster way to clear the screen than to
|
|
write spaces in all character cells, then it can be implemented here. If the
|
|
driver does not implement this function, then the general routines will
|
|
write spaces in all video cells, and will call \var{UpdateScreen(True)}.
|
|
\item[SetVideoMode] Should set the desired video mode, if available. It
|
|
should return \var{True} if the mode was set, \var{False} if not.
|
|
\item[GetVideoModeCount] Should return the number of supported video modes.
|
|
If no modes are supported, this function should not be implemented; the
|
|
general routines will return 1. (for the current mode)
|
|
\item[GetVideoModeData] Should return the data for the \var{Index}-th mode;
|
|
\var{Index} is zero based. The function should return true if the data was
|
|
returned correctly, false if \var{Index} contains an invalid index.
|
|
If this is not implemented, then the general routine will return the current
|
|
video mode when \var{Index} equals 0.
|
|
\item[GetCapabilities] If this function is not implemented, zero (i.e.
|
|
no capabilities) will be returned by the general function.
|
|
\end{description}
|
|
|
|
The following unit shows how to override a video driver, with a driver
|
|
that writes debug information to a file.
|
|
|
|
\FPCexample{viddbg}
|
|
|
|
The unit can be used in any of the demonstration programs, by simply
|
|
including it in the \var{uses} clause. Setting \var{DetailedVideoLogging} to
|
|
\var{True} will create a more detailed log (but will also slow down
|
|
functioning) |