📄 dxdraws.pas
字号:
end;
implementation
uses DXConsts, DXRender;
function DXDirectDrawEnumerate(lpCallback: LPDDENUMCALLBACKA;
lpContext: Pointer): HRESULT;
type
TDirectDrawEnumerate = function(lpCallback: LPDDENUMCALLBACKA;
lpContext: Pointer): HRESULT; stdcall;
begin
Result := TDirectDrawEnumerate(DXLoadLibrary('DDraw.dll', 'DirectDrawEnumerateA'))
(lpCallback, lpContext);
end;
var
DirectDrawDrivers: TDirectXDrivers;
function EnumDirectDrawDrivers: TDirectXDrivers;
function DDENUMCALLBACK(lpGuid: PGUID; lpstrDescription: LPCSTR;
lpstrModule: LPCSTR; lpContext: Pointer): BOOL; stdcall;
begin
Result := True;
with TDirectXDriver.Create(TDirectXDrivers(lpContext)) do
begin
Guid := lpGuid;
Description := lpstrDescription;
DriverName := lpstrModule;
end;
end;
begin
if DirectDrawDrivers=nil then
begin
DirectDrawDrivers := TDirectXDrivers.Create;
try
DXDirectDrawEnumerate(@DDENUMCALLBACK, DirectDrawDrivers);
except
DirectDrawDrivers.Free;
raise;
end;
end;
Result := DirectDrawDrivers;
end;
function ClipRect(var DestRect: TRect; const DestRect2: TRect): Boolean;
begin
with DestRect do
begin
Left := Max(Left, DestRect2.Left);
Right := Min(Right, DestRect2.Right);
Top := Max(Top, DestRect2.Top);
Bottom := Min(Bottom, DestRect2.Bottom);
Result := (Left < Right) and (Top < Bottom);
end;
end;
function ClipRect2(var DestRect, SrcRect: TRect; const DestRect2, SrcRect2: TRect): Boolean;
begin
if DestRect.Left < DestRect2.Left then
begin
SrcRect.Left := SrcRect.Left + (DestRect2.Left - DestRect.Left);
DestRect.Left := DestRect2.Left;
end;
if DestRect.Top < DestRect2.Top then
begin
SrcRect.Top := SrcRect.Top + (DestRect2.Top - DestRect.Top);
DestRect.Top := DestRect2.Top;
end;
if SrcRect.Left < SrcRect2.Left then
begin
DestRect.Left := DestRect.Left + (SrcRect2.Left - SrcRect.Left);
SrcRect.Left := SrcRect2.Left;
end;
if SrcRect.Top < SrcRect2.Top then
begin
DestRect.Top := DestRect.Top + (SrcRect2.Top - SrcRect.Top);
SrcRect.Top := SrcRect2.Top;
end;
if DestRect.Right > DestRect2.Right then
begin
SrcRect.Right := SrcRect.Right - (DestRect.Right - DestRect2.Right);
DestRect.Right := DestRect2.Right;
end;
if DestRect.Bottom > DestRect2.Bottom then
begin
SrcRect.Bottom := SrcRect.Bottom - (DestRect.Bottom - DestRect2.Bottom);
DestRect.Bottom := DestRect2.Bottom;
end;
if SrcRect.Right > SrcRect2.Right then
begin
DestRect.Right := DestRect.Right - (SrcRect.Right - SrcRect2.Right);
SrcRect.Right := SrcRect2.Right;
end;
if SrcRect.Bottom > SrcRect2.Bottom then
begin
DestRect.Bottom := DestRect.Bottom - (SrcRect.Bottom - SrcRect2.Bottom);
SrcRect.Bottom := SrcRect2.Bottom;
end;
Result := (DestRect.Left < DestRect.Right) and
(DestRect.Top < DestRect.Bottom) and
(SrcRect.Left < SrcRect.Right) and
(SrcRect.Top < SrcRect.Bottom);
end;
{ TDirectDraw }
constructor TDirectDraw.Create(GUID: PGUID);
type
TDirectDrawCreate = function(lpGUID: PGUID; out lplpDD: IDirectDraw;
pUnkOuter: IUnknown): HRESULT; stdcall;
var
DDraw: IDirectDraw;
begin
if TDirectDrawCreate(DXLoadLibrary('DDraw.dll', 'DirectDrawCreate')) (GUID, DDraw, DDraw)=DD_OK then
CreateFromInterface(DDraw)
else
CreateFromInterface(nil);
end;
constructor TDirectDraw.CreateFromInterface(DDraw: IDirectDraw);
begin
inherited Create;
FClippers := TList.Create;
FPalettes := TList.Create;
FSurfaces := TList.Create;
FIDDraw := DDraw;
if FIDDraw=nil then
raise EDirectDrawError.CreateFmt(SCannotInitialized, [SDirectDraw]);
try
FIDDraw4 := FIDDraw as IDirectDraw4;
except
raise EDirectDrawError.Create(SSinceDirectX6);
end;
FDriverCaps.dwSize := SizeOf(FDriverCaps);
FHELCaps.dwSize := SizeOf(FHELCaps);
FIDDraw4.GetCaps(FDriverCaps, FHELCaps);
end;
destructor TDirectDraw.Destroy;
begin
while SurfaceCount>0 do
Surfaces[SurfaceCount-1].Free;
while PaletteCount>0 do
Palettes[PaletteCount-1].Free;
while ClipperCount>0 do
Clippers[ClipperCount-1].Free;
FSurfaces.Free;
FPalettes.Free;
FClippers.Free;
inherited Destroy;
end;
class function TDirectDraw.Drivers: TDirectXDrivers;
begin
Result := EnumDirectDrawDrivers;
end;
function TDirectDraw.GetClipper(Index: Integer): TDirectDrawClipper;
begin
Result := FClippers[Index];
end;
function TDirectDraw.GetClipperCount: Integer;
begin
Result := FClippers.Count;
end;
function TDirectDraw.GetDisplayMode: TDDSurfaceDesc;
begin
Result.dwSize := SizeOf(Result);
DXResult := IDraw.GetDisplayMode(Result);
if DXResult<>DD_OK then
FillChar(Result, SizeOf(Result), 0);
end;
function TDirectDraw.GetIDDraw: IDirectDraw;
begin
if Self<>nil then
Result := FIDDraw
else
Result := nil;
end;
function TDirectDraw.GetIDDraw4: IDirectDraw4;
begin
if Self<>nil then
Result := FIDDraw4
else
Result := nil;
end;
function TDirectDraw.GetIDraw: IDirectDraw;
begin
Result := IDDraw;
if Result=nil then
raise EDirectDrawError.CreateFmt(SNotMade, ['IDirectDraw']);
end;
function TDirectDraw.GetIDraw4: IDirectDraw4;
begin
Result := IDDraw4;
if Result=nil then
raise EDirectDrawError.CreateFmt(SNotMade, ['IDirectDraw4']);
end;
function TDirectDraw.GetPalette(Index: Integer): TDirectDrawPalette;
begin
Result := FPalettes[Index];
end;
function TDirectDraw.GetPaletteCount: Integer;
begin
Result := FPalettes.Count;
end;
function TDirectDraw.GetSurface(Index: Integer): TDirectDrawSurface;
begin
Result := FSurfaces[Index];
end;
function TDirectDraw.GetSurfaceCount: Integer;
begin
Result := FSurfaces.Count;
end;
{ TDirectDrawPalette }
constructor TDirectDrawPalette.Create(ADirectDraw: TDirectDraw);
begin
inherited Create;
FDDraw := ADirectDraw;
FDDraw.FPalettes.Add(Self);
end;
destructor TDirectDrawPalette.Destroy;
begin
FDDraw.FPalettes.Remove(Self);
inherited Destroy;
end;
function TDirectDrawPalette.CreatePalette(Caps: Integer;
const Entries): Boolean;
var
TempPalette: IDirectDrawPalette;
begin
IDDPalette := nil;
FDDraw.DXResult := FDDraw.IDraw.CreatePalette(Caps, @Entries, TempPalette, nil);
FDXResult := FDDraw.DXResult;
Result := FDDraw.DXResult=DD_OK;
if Result then
IDDPalette := TempPalette;
end;
procedure TDirectDrawPalette.LoadFromDIB(DIB: TDIB);
var
Entries: TPaletteEntries;
begin
Entries := RGBQuadsToPaletteEntries(DIB.ColorTable);
CreatePalette(DDPCAPS_8BIT, Entries);
end;
procedure TDirectDrawPalette.LoadFromFile(const FileName: string);
var
Stream: TFileStream;
begin
Stream := TFileStream.Create(FileName, fmOpenRead);
try
LoadFromStream(Stream);
finally
Stream.Free;
end;
end;
procedure TDirectDrawPalette.LoadFromStream(Stream: TStream);
var
DIB: TDIB;
begin
DIB := TDIB.Create;
try
DIB.LoadFromStream(Stream);
if DIB.Size>0 then
LoadFromDIB(DIB);
finally
DIB.Free;
end;
end;
function TDirectDrawPalette.GetEntries(StartIndex, NumEntries: Integer;
var Entries): Boolean;
begin
if IDDPalette<>nil then
begin
DXResult := IPalette.GetEntries(0, StartIndex, NumEntries, @Entries);
Result := DXResult=DD_OK;
end else
Result := False;
end;
function TDirectDrawPalette.GetEntry(Index: Integer): TPaletteEntry;
begin
GetEntries(Index, 1, Result);
end;
function TDirectDrawPalette.GetIDDPalette: IDirectDrawPalette;
begin
if Self<>nil then
Result := FIDDPalette
else
Result := nil;
end;
function TDirectDrawPalette.GetIPalette: IDirectDrawPalette;
begin
Result := IDDPalette;
if Result=nil then
raise EDirectDrawPaletteError.CreateFmt(SNotMade, ['IDirectDrawPalette']);
end;
function TDirectDrawPalette.SetEntries(StartIndex, NumEntries: Integer;
const Entries): Boolean;
begin
if IDDPalette<>nil then
begin
DXResult := IPalette.SetEntries(0, StartIndex, NumEntries, @Entries);
Result := DXResult=DD_OK;
end else
Result := False;
end;
procedure TDirectDrawPalette.SetEntry(Index: Integer; Value: TPaletteEntry);
begin
SetEntries(Index, 1, Value);
end;
procedure TDirectDrawPalette.SetIDDPalette(Value: IDirectDrawPalette);
begin
FIDDPalette := Value;
end;
{ TDirectDrawClipper }
constructor TDirectDrawClipper.Create(ADirectDraw: TDirectDraw);
begin
inherited Create;
FDDraw := ADirectDraw;
FDDraw.FClippers.Add(Self);
FDDraw.DXResult := FDDraw.IDraw.CreateClipper(0, FIDDClipper, nil);
if FDDraw.DXResult<>DD_OK then
raise EDirectDrawClipperError.CreateFmt(SCannotMade, [SDirectDrawClipper]);
end;
destructor TDirectDrawClipper.Destroy;
begin
FDDraw.FClippers.Remove(Self);
inherited Destroy;
end;
function TDirectDrawClipper.GetIDDClipper: IDirectDrawClipper;
begin
if Self<>nil then
Result := FIDDClipper
else
Result := nil;
end;
function TDirectDrawClipper.GetIClipper: IDirectDrawClipper;
begin
Result := IDDClipper;
if Result=nil then
raise EDirectDrawClipperError.CreateFmt(SNotMade, ['IDirectDrawClipper']);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -