fpc/rtl/linux/ggigraph.inc
2000-01-07 16:41:28 +00:00

476 lines
13 KiB
PHP

{
$Id$
This file is part of the Free Pascal run time library.
Copyright (c) 1999-2000 by the Free Pascal development team
GGI implementation of graph unit.
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program 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.
**********************************************************************}
{$LINKLIB c}
{$PACKRECORDS C}
const
InternalDriverName = 'LinuxGGI';
var
SavePtr: Pointer;
{ ---------------------------------------------------------------------
GGI bindings [(c) 1999 Sebastian Guenther]
---------------------------------------------------------------------}
const
GLASTMODE = 49;
ModeNames: array[0..GLastMode] of PChar =
('[]', {Let GGI choose a default mode}
'S320x200[GT_4BIT]',
'S640x200[GT_4BIT]',
'S640x350[GT_4BIT]',
'S640x480[GT_4BIT]',
'S320x200[GT_8BIT]',
'S320x240[GT_8BIT]',
'S320x400[GT_8BIT]',
'S360x480[GT_8BIT]',
'S640x480x[GT_1BIT]',
'S640x480[GT_8BIT]',
'S800x600[GT_8BIT]',
'S1024x768[GT_8BIT]',
'S1280x1024[GT_8BIT]',
'S320x200[GT_15BIT]',
'S320x200[GT_16BIT]',
'S320x200[GT_24BIT]',
'S640x480[GT_15BIT]',
'S640x480[GT_16BIT]',
'S640x480[GT_24BIT]',
'S800x600[GT_15BIT]',
'S800x600[GT_16BIT]',
'S800x600[GT_24BIT]',
'S1024x768[GT_15BIT]',
'S1024x768[GT_16BIT]',
'S1024x768[GT_24BIT]',
'S1280x1024[GT_15BIT]',
'S1280x1024[GT_16BIT]',
'S1280x1024[GT_24BIT]',
'S800x600[GT_4BIT]',
'S1024x768[GT_4BIT]',
'S1280x1024[GT_4BIT]',
'S720x348x[GT_1BIT]',
'S320x200[GT_32BIT]',
'S640x480[GT_32BIT]',
'S800x600[GT_32BIT]',
'S1024x768[GT_32BIT]',
'S1280x1024[GT_32BIT]',
'S1152x864[GT_4BIT]',
'S1152x864[gt_8BIT]',
'S1152x864[GT_15BIT]',
'S1152x864[GT_16BIT]',
'S1152x864[GT_24BIT]',
'S1152x864[GT_32BIT]',
'S1600x1200[GT_4BIT]',
'S1600x1200[gt_8BIT]',
'S1600x1200[GT_15BIT]',
'S1600x1200[GT_16BIT]',
'S1600x1200[GT_24BIT]',
'S1600x1200[GT_32BIT]');
type
TGGIVisual = Pointer;
TGGIResource = Pointer;
TGGICoord = record
x, y: SmallInt;
end;
TGGIPixel = LongWord;
PGGIColor = ^TGGIColor;
TGGIColor = record
r, g, b, a: Word;
end;
PGGIClut = ^TGGIClut;
TGGIClut = record
size: SmallInt;
data: PGGIColor;
end;
TGGIGraphType = LongWord;
TGGIAttr = LongWord;
TGGIMode = record // requested by user and changed by driver
Frames: LongInt; // frames needed
Visible: TGGICoord; // vis. pixels, may change slightly
Virt: TGGICoord; // virtual pixels, may change
Size: TGGICoord; // size of visible in mm
GraphType: TGGIGraphType; // which mode ?
dpp: TGGICoord; // dots per pixel
end;
const
libggi = 'ggi';
function ggiInit: Longint; cdecl; external libggi;
procedure ggiExit; cdecl; external libggi;
function ggiOpen(display: PChar; args: Array of const): TGGIVisual; cdecl; external libggi;
function ggiClose(vis: TGGIVisual): Longint; cdecl; external libggi;
function ggiParseMode(s: PChar; var m: TGGIMode): Longint; cdecl; external libggi;
function ggiSetMode(visual: TGGIVisual; var tm: TGGIMode): Longint; cdecl; external libggi;
function ggiGetMode(visual: TGGIVisual; var tm: TGGIMode): Longint; cdecl; external libggi;
function ggiCheckMode(visual: TGGIVisual; var tm: TGGIMode): Longint; cdecl; external libggi;
function ggiMapColor(vis: TGGIVisual; Color: TGGIColor): TGGIPixel; cdecl; external libggi;
function ggiPutPixel(vis: TGGIVisual; x, y: Longint; pixel: TGGIPixel): Longint; cdecl; external libggi;
function ggiGetPixel(vis: TGGIVisual; x, y: Longint; var pixel: TGGIPixel): Longint; cdecl; external libggi;
function ggiDrawBox(vis: TGGIVisual; x, y, w, h: Longint): Longint; cdecl; external libggi;
function ggiPutBox(vis: TGGIVisual; x, y, w, h: Longint; var buffer): Longint; cdecl; external libggi;
function ggiGetBox(vis: TGGIVisual; x, y, w, h: Longint; var buffer): Longint; cdecl; external libggi;
function ggiGetPalette(vis: TGGIVisual; s, len: Longint; var cmap: TGGIColor): Longint; cdecl; external libggi;
function ggiSetPalette(vis: TGGIVisual; s, len: Longint; var cmap: TGGIColor): Longint; cdecl; external libggi;
var
Visual: TGGIVisual;
CurrentMode, OldMode: TGGIMode;
procedure ggi_savevideostate;
begin
ggiGetMode(Visual, OldMode);
end;
procedure ggi_restorevideostate;
begin
ggiSetMode(Visual, OldMode);
end;
const
BgiColors: array[0..15] of TGGIColor = (
(r: $0000; g: $0000; b: $0000; a: 0),
(r: $0000; g: $0000; b: $8000; a: 0),
(r: $0000; g: $8000; b: $0000; a: 0),
(r: $0000; g: $8000; b: $8000; a: 0),
(r: $8000; g: $0000; b: $0000; a: 0),
(r: $8000; g: $0000; b: $8000; a: 0),
(r: $8000; g: $8000; b: $0000; a: 0),
(r: $C000; g: $C000; b: $C000; a: 0),
(r: $8000; g: $8000; b: $8000; a: 0),
(r: $0000; g: $0000; b: $FFFF; a: 0),
(r: $0000; g: $FFFF; b: $0000; a: 0),
(r: $0000; g: $FFFF; b: $FFFF; a: 0),
(r: $FFFF; g: $0000; b: $0000; a: 0),
(r: $FFFF; g: $0000; b: $FFFF; a: 0),
(r: $FFFF; g: $FFFF; b: $0000; a: 0),
(r: $FFFF; g: $FFFF; b: $FFFF; a: 0));
procedure ggi_initmodeproc;
begin
ggiParseMode(ModeNames[IntCurrentMode], CurrentMode);
ggiSetMode(Visual, CurrentMode);
end;
function ClipCoords(var x, y: SmallInt): Boolean;
{ Adapt to viewport, return TRUE if still in viewport,
false if outside viewport}
begin
x := x + StartXViewPort;
x := y + StartYViewPort;
ClipCoords := not ClipPixels;
if ClipCoords then begin
ClipCoords := (y < StartXViewPort) or (x > (StartXViewPort + ViewWidth));
ClipCoords := ClipCoords or
((y < StartYViewPort) or (y > (StartYViewPort + ViewHeight)));
ClipCoords := not ClipCoords;
end;
end;
procedure ggi_directpixelproc(X, Y: smallint);
var
Color, CurCol: TGGIPixel;
begin
CurCol := ggiMapColor(Visual, BgiColors[CurrentColor]);
case CurrentWriteMode of
XORPut: begin
{ getpixel wants local/relative coordinates }
ggiGetPixel(Visual, x-StartXViewPort, y-StartYViewPort, Color);
Color := CurCol xor Color;
end;
OrPut: begin
{ getpixel wants local/relative coordinates }
ggiGetPixel(Visual, x-StartXViewPort, y-StartYViewPort, Color);
Color := CurCol or Color;
end;
AndPut: begin
{ getpixel wants local/relative coordinates }
ggiGetPixel(Visual, x-StartXViewPort, y-StartYViewPort, Color);
Color := CurCol and Color;
end;
NotPut:
Color := not Color;
else
Color := CurCol;
end;
ggiPutPixel(Visual, x, y, Color);
end;
procedure ggi_putpixelproc(X,Y: smallint; Color: Word);
begin
If Not ClipCoords(X,Y) Then exit;
ggiputpixel(Visual,x, y, Color);
end;
function ggi_getpixelproc (X,Y: smallint): word;
Var i : TGGIPixel;
begin
ClipCoords(X,Y);
ggigetpixel(Visual,x, y,I);
ggi_getpixelproc:=i;
end;
procedure ggi_clrviewproc;
begin
ggidrawbox(Visual,StartXViewPort,StartYViewPort,ViewWidth,ViewHeight);
end;
{ Bitmap utilities }
type
PBitmap = ^TBitmap;
TBitmap = record
Width, Height: longint;
reserved : longint;
Data: record end;
end;
procedure ggi_putimageproc (X,Y: smallint; var Bitmap; BitBlt: Word);
begin
With TBitMap(BitMap) do
ggiputbox(Visual,x, y, width, height, @Data);
end;
procedure ggi_getimageproc (X1,Y1,X2,Y2: smallint; Var Bitmap);
begin
with TBitmap(Bitmap) do
begin
Width := x2 - x1 + 1;
Height := y2 - y1 + 1;
ggigetbox(Visual,x1,y1, x2 - x1 + 1, y2 - y1 + 1, @Data);
end;
end;
function ggi_imagesizeproc (X1,Y1,X2,Y2: smallint): longint;
begin
// 32 bits per pixel -- change ASAP !!
ggi_imagesizeproc := SizeOf(TBitmap) + (x2 - x1 + 1) * (y2 - y1 + 1) * SizeOF(longint);
end;
procedure ggi_hlineproc (x, x2,y : smallint);
begin
end;
procedure ggi_vlineproc (x,y,y2: smallint);
begin
end;
procedure ggi_patternlineproc (x1,x2,y: smallint);
begin
end;
procedure ggi_ellipseproc (X,Y: smallint;XRadius: word;
YRadius:word; stAngle,EndAngle: word; fp: PatternLineProc);
begin
end;
procedure ggi_lineproc (X1, Y1, X2, Y2 : smallint);
begin
end;
procedure ggi_getscanlineproc (X1, X2, Y : smallint; var data);
begin
end;
procedure ggi_setactivepageproc (page: word);
begin
end;
procedure ggi_setvisualpageproc (page: word);
begin
end;
procedure ggi_savestateproc;
begin
end;
procedure ggi_restorestateproc;
begin
end;
procedure ggi_setrgbpaletteproc(ColorNum, RedValue, GreenValue, BlueValue: smallint);
Var Col : TGGIcolor;
begin
col.r:=redvalue;
col.g:=greenvalue;
col.b:=bluevalue;
ggisetpalette(Visual,ColorNum,1,col);
end;
procedure ggi_getrgbpaletteproc (ColorNum: smallint;
var RedValue, GreenValue, BlueValue: smallint);
Var Col : TGGIColor;
begin
ggigetpalette(Visual,ColorNum,1,col);
RedValue:=Col.R;
GreenValue:=Col.G;
BlueValue:=Col.B;
end;
{************************************************************************}
{* General routines *}
{************************************************************************}
procedure CloseGraph;
begin
if not IsGraphMode then
begin
_graphresult := grnoinitgraph;
exit
end;
RestoreVideoState;
isgraphmode := false;
end;
function QueryAdapterInfo:PModeInfo;
{ This routine returns the head pointer to the list }
{ of supported graphics modes. }
{ Returns nil if no graphics mode supported. }
{ This list is READ ONLY! }
var
ModeInfo: TGGIMode;
procedure AddGGIMode(i: smallint); // i is the mode number
var
mode: TModeInfo;
begin
InitMode(Mode);
with Mode do begin
ModeNumber := i;
ModeName := ModeNames[i];
// Pretend we're VGA always.
DriverNumber := VGA;
MaxX := ModeInfo.Visible.X;
MaxY := ModeInfo.Visible.Y;
// MaxColor := ModeInfo.colors;
MaxColor := 255;
PaletteSize := MaxColor;
HardwarePages := 0;
// necessary hooks ...
DirectPutPixel := @ggi_DirectPixelProc;
GetPixel := @ggi_GetPixelProc;
PutPixel := @ggi_PutPixelProc;
SetRGBPalette := @ggi_SetRGBPaletteProc;
GetRGBPalette := @ggi_GetRGBPaletteProc;
ClearViewPort := @ggi_ClrViewProc;
PutImage := @ggi_PutImageProc;
GetImage := @ggi_GetImageProc;
ImageSize := @ggi_ImageSizeProc;
{ Add later maybe ?
SetVisualPage := SetVisualPageProc;
SetActivePage := SetActivePageProc;
GetScanLine := @ggi_GetScanLineProc;
Line := @ggi_LineProc;
InternalEllipse:= @ggi_EllipseProc;
PatternLine := @ggi_PatternLineProc;
HLine := @ggi_HLineProc;
VLine := @ggi_VLineProc;
}
InitMode := @ggi_InitModeProc;
end;
AddMode(Mode);
end;
var
i: longint;
OldMode: TGGIMode;
begin
QueryAdapterInfo := ModeList;
{ If the mode listing already exists... }
{ simply return it, without changing }
{ anything... }
if Assigned(ModeList) then
exit;
SaveVideoState:=ggi_savevideostate;
RestoreVideoState:=ggi_restorevideostate;
If ggiInit <> 0 then begin
_graphresult := grNoInitGraph;
exit;
end;
Visual := ggiOpen(nil, []); // Use default visual
ggiGetMode(Visual, OldMode);
ggiParseMode('', ModeInfo);
ggiSetMode(Visual, ModeInfo);
ggiGetMode(Visual, ModeInfo);
ggiSetMode(Visual, OldMode);
AddGGIMode(0);
for i := 1 to GLastMode do begin
// WriteLn('Testing mode: ', ModeNames[i]);
ggiParseMode(ModeNames[i], ModeInfo);
If ggiCheckMode(visual, ModeInfo) = 0 then begin
Writeln('OK for mode: ', ModeNames[i]);
AddGGIMode(i);
end;
end;
end;
{
$Log$
Revision 1.8 2000-01-07 16:41:40 daniel
* copyright 2000
Revision 1.7 1999/12/20 11:22:38 peter
* modes moved to interface
* integer -> smallint
Revision 1.6 1999/12/11 23:41:39 jonas
* changed definition of getscanlineproc to "getscanline(x1,x2,y:
smallint; var data);" so it can be used by getimage too
* changed getimage so it uses getscanline
* changed floodfill, getscanline16 and definitions in Linux
include files so they use this new format
+ getscanlineVESA256 for 256 color VESA modes (banked)
Revision 1.5 1999/11/12 02:13:01 carl
* Bugfix if getimage / putimage, format was not standard with FPC
graph.
Revision 1.4 1999/11/10 10:54:24 sg
* Fixed a LOT of bugs:
* - Default mode should be determined by GGI now
* - Colors are working (only the 16 standard VGA colors, though)
Revision 1.3 1999/11/08 20:04:55 sg
* GGI programs must link to libc, or ggiOpen will fail!
* Changed max length of ModeNames string from 18 to 20 chars
Revision 1.2 1999/11/08 00:08:43 michael
* Fist working version of svgalib new graph unit
* Initial implementation of ggi new graph unit
Revision 1.1 1999/11/07 16:57:26 michael
+ Start of common graph implementation
}