{ This file is part of the Free Pascal run time library. Copyright (c) 2007 by Daniel Mantione member of the Free Pascal development team This file implements the PTC support for the 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. **********************************************************************} unit ptcgraph; {$define logging} {******************************************************************************} interface {******************************************************************************} {$i graphh.inc} {Driver number for PTC.} const PTC=22; {******************************************************************************} implementation {******************************************************************************} uses termio,x86,ptc; const InternalDriverName = 'PTCPas'; {$i graph.inc} type PByte = ^Byte; PLongInt = ^LongInt; PByteArray = ^TByteArray; TByteArray = array [0..MAXINT - 1] of Byte; { --------------------------------------------------------------------- SVGA bindings. ---------------------------------------------------------------------} Const { Text } WRITEMODE_OVERWRITE = 0; WRITEMODE_MASKED = 1; FONT_EXPANDED = 0; FONT_COMPRESSED = 2; { Types } type pvga_modeinfo = ^vga_modeinfo; vga_modeinfo = record width, height, bytesperpixel, colors, linewidth, { scanline width in bytes } maxlogicalwidth, { maximum logical scanline width } startaddressrange, { changeable bits set } maxpixels, { video memory / bytesperpixel } haveblit, { mask of blit functions available } flags: Longint; { other flags } { Extended fields: } chiptype, { Chiptype detected } memory, { videomemory in KB } linewidth_unit: Longint; { Use only a multiple of this as parameter for set_displaystart } linear_aperture: PChar; { points to mmap secondary mem aperture of card } aperture_size: Longint; { size of aperture in KB if size>=videomemory.} set_aperture_page: procedure (page: Longint); { if aperture_size (StartXViewPort + ViewWidth)); ClipCoords:=ClipCoords or ((Y < StartYViewPort) or (Y > (StartYViewPort + ViewHeight))); ClipCoords:=Not ClipCoords; end; end; procedure ptc_directpixelproc_16bpp(X,Y: smallint); var color:word; pixels:Pword; begin case CurrentWriteMode of XORPut: begin { getpixel wants local/relative coordinates } Color := GetPixel(x-StartXViewPort,y-StartYViewPort); Color := CurrentColor Xor Color; end; OrPut: begin { getpixel wants local/relative coordinates } Color := GetPixel(x-StartXViewPort,y-StartYViewPort); Color := CurrentColor Or Color; end; AndPut: begin { getpixel wants local/relative coordinates } Color := GetPixel(x-StartXViewPort,y-StartYViewPort); Color := CurrentColor And Color; end; NotPut: begin Color := Not Color; end else Color:=CurrentColor; end; pixels:=ptcsurface.lock; {Plot the pixel on the surface.} pixels[x+y*ptcsurface.width]:=color; ptcsurface.unlock; { copy to console } ptcsurface.copy(ptcconsole); { update console } ptcconsole.update; end; procedure ptc_putpixelproc_16bpp(X,Y:smallint;Color:Word); var pixels:Pword; begin if clipcoords(X,Y) then begin pixels:=ptcsurface.lock; { pixels:=ptcconsole.lock;} {Plot the pixel on the surface.} pixels[x+y*ptcsurface.width]:=color; ptcsurface.unlock; { copy to console } ptcsurface.copy(ptcconsole); { update console } ptcconsole.update; end; end; function ptc_getpixelproc_16bpp(X,Y: smallint):word; var pixels:Pword; begin if clipcoords(X,Y) then begin pixels:=ptcsurface.lock; {Get the pixel from the surface.} ptc_getpixelproc_16bpp:=pixels[x+y*ptcsurface.width]; ptcsurface.unlock; end; end; { Bitmap utilities } {type PBitmap = ^TBitmap; TBitmap = record Width, Height: smallint; Data: record end; end; } procedure ptc_putimageproc (X,Y: smallint; var Bitmap; BitBlt: Word); begin end; procedure ptc_getimageproc (X1,Y1,X2,Y2: smallint; Var Bitmap); begin end; function ptc_imagesizeproc (X1,Y1,X2,Y2: smallint): longint; begin end; procedure ptc_hlineproc_16bpp(x, x2,y : smallint); var pixels:Pword; i:word; begin {Clip.} if (y<0) or (y>viewheight) then exit; if x<0 then x:=0; if x>viewwidth then x:=viewwidth; if x2<0 then x2:=0; if x>viewwidth then x2:=viewwidth; pixels:=ptcsurface.lock; inc(x,StartXViewPort); inc(x2,StartXViewPort); inc(y,StartXViewPort); {Plot the pixel on the surface.} for i:=x to x2 do pixels[i+y*ptcsurface.width]:=$ffff; ptcsurface.unlock; { copy to console } ptcsurface.copy(ptcconsole); { update console } ptcconsole.update; end; procedure ptc_vlineproc (x,y,y2: smallint); begin end; procedure ptc_clrviewproc_16bpp; Var I,Xmax : longint; begin Xmax:=StartXViewPort+ViewWidth-1; For i:=StartYViewPort to StartYViewPort+ViewHeight-1 do ptc_hlineproc_16bpp(0,viewwidth,i); { reset coordinates } CurrentX := 0; CurrentY := 0; end; procedure ptc_patternlineproc (x1,x2,y: smallint); begin end; procedure ptc_ellipseproc (X,Y: smallint;XRadius: word; YRadius:word; stAngle,EndAngle: word; fp: PatternLineProc); begin end; procedure ptc_lineproc (X1, Y1, X2, Y2 : smallint); begin end; procedure ptc_getscanlineproc (X1,X2,Y : smallint; var data); begin end; procedure ptc_setactivepageproc (page: word); begin end; procedure ptc_setvisualpageproc (page: word); begin end; procedure ptc_savestateproc; begin end; procedure ptc_restorestateproc; begin end; procedure ptc_setrgbpaletteproc(ColorNum, RedValue, GreenValue, BlueValue: smallint); begin { vga_setpalette(ColorNum,RedValue shr 2,GreenValue shr 2,BlueValue shr 2);} end; procedure ptc_getrgbpaletteproc (ColorNum: smallint; var RedValue, GreenValue, BlueValue: smallint); Var R,G,B : longint; begin { vga_getpalette(ColorNum,R,G,B);} RedValue:=R * 255 div 63; GreenValue:=G * 255 div 63; BlueValue:=B * 255 div 63; end; {************************************************************************} {* General routines *} {************************************************************************} procedure CloseGraph; Begin If not isgraphmode then begin _graphresult := grnoinitgraph; exit end; SetRawMode(False); 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 graphmode:Tmodeinfo; ptcmode: PPTCmode; d,i : longint; ws,hs:string[5]; const depths:array[0..3] of byte=(8,16,24,32); colours:array[0..3] of longint=(256,65536,16777216,16777216); depth_names:array[0..3] of string[5]=('256','64K','16M','16M32'); begin QueryAdapterInfo := ModeList; { If the mode listing already exists... } { simply return it, without changing } { anything... } if assigned(ModeList) then exit; SaveVideoState:=@ptc_savevideostate; RestoreVideoState:=@ptc_restorevideostate; ptcconsole:=TPTCconsole.create; ptcmode:=ptcconsole.modes; i:=0; initmode(graphmode); with graphmode do begin modenumber:=0; drivernumber:=ptcgraph.ptc; maxx:=639; maxy:=479; modename:='PTC_640x480x64K'; maxcolor:=65536; palettesize:=65536; hardwarepages:=0; InitMode := @ptc_InitModeProc; DirectPutPixel := @ptc_DirectPixelProc_16bpp; GetPixel := @ptc_GetPixelProc_16bpp; PutPixel := @ptc_PutPixelProc_16bpp; SetRGBPalette := @ptc_SetRGBPaletteProc; GetRGBPalette := @ptc_GetRGBPaletteProc; end; addmode(graphmode); (* writeln('processing modes'); while ptcmode^.valid do begin for d:=low(depths) to high(depths) do begin InitMode(graphmode); with graphmode do begin ModeNumber:=I; DriverNumber:=ptcgraph.PTC; { MaxX is number of pixels in X direction - 1} MaxX:=ptcmode^.width-1; { same for MaxY} MaxY:=ptcmode^.height-1; str(ptcmode^.width,ws); str(ptcmode^.height,hs); modename:='PTC_'+ws+'x'+hs+'x'+depth_names[d]; MaxColor := 1 shl ptcmode^.format.r * 1 shl ptcmode^.format.g *1 shl ptcmode^.format.b; writeln('mode ',modename,' ',maxcolor,'kleuren'); PaletteSize := MaxColor; HardwarePages := 0; *) { necessary hooks ...} (* if (MaxColor = 16) and (LongInt(ModeInfo.Width) * LongInt(ModeInfo.Height) < 65536*4*2) then begin {Use optimized graphics routines for 4 bit EGA/VGA modes.} ScrWidth := ModeInfo.Width div 8; DirectPutPixel := @DirectPutPixel16; PutPixel := @PutPixel16; GetPixel := @GetPixel16; HLine := @HLine16; VLine := @VLine16; GetScanLine := @GetScanLine16; end else *) (* begin DirectPutPixel := @ptc_DirectPixelProc; GetPixel := @ptc_GetPixelProc; PutPixel := @ptc_PutPixelProc; { May be implemented later: HLine := @libvga_HLineProc; VLine := @libvga_VLineProc; GetScanLine := @libvga_GetScanLineProc;} ClearViewPort := @ptc_ClrViewProc; end; SetRGBPalette := @ptc_SetRGBPaletteProc; GetRGBPalette := @ptc_GetRGBPaletteProc; { These are not really implemented yet: PutImage := @libvga_PutImageProc; GetImage := @libvga_GetImageProc;} { If you use the default getimage/putimage, you also need the default imagesize! (JM) ImageSize := @libvga_ImageSizeProc; } { Add later maybe ? SetVisualPage := SetVisualPageProc; SetActivePage := SetActivePageProc; Line := @libvga_LineProc; InternalEllipse:= @libvga_EllipseProc; PatternLine := @libvga_PatternLineProc; } InitMode := @ptc_InitModeProc; end; AddMode(graphmode); inc(i); end; end; *) end; initialization ptcconsole:=TPTCconsole.create; InitializeGraph; finalization ptcconsole.destroy; end.