📄 rw_ddraw.pas
字号:
{----------------------------------------------------------------------------}
{ }
{ File(s): rw_draw.h - This handles DirecTDraw management under Windows. }
{ }
{ Initial conversion (90%) by : Savage (Dominique@SavageSoftware.com.au) }
{ Final conversion by : Massimo (max-67@libero.it) }
{ Initial conversion on : 09-Jan-2002 }
{ }
{ This File contains part of convertion of Quake2 source to ObjectPascal. }
{ More information about this project can be found at: }
{ http://www.sulaco.co.za/quake2/ }
{ }
{ Copyright (C) 1997-2001 Id Software, Inc. }
{ }
{ This program is free software; you can redistribute it and/or }
{ modify it under the terms of the GNU General Public License }
{ as published by the Free Software Foundation; either version 2 }
{ of the License, or (at your option) any later version. }
{ }
{ 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. }
{ }
{ See the GNU General Public License for more details. }
{ }
{----------------------------------------------------------------------------}
{ Updated on : 07-August-2002 }
{ Updated by : CodeFusion(Michael@Skovslund.dk) }
{ }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on: }
{ 1) ? }
{----------------------------------------------------------------------------}
{ * TODO: }
{ 1) ? }
{----------------------------------------------------------------------------}
unit rw_ddraw;
interface
uses
Windows,
SysUtils,
q_shared,
r_local;
//var
// d_8to24table: array[0..255] of Word;
type
PPByte = ^PByte;
function DDrawError(code: integer): string;
function DDRAW_Init(ppbuffer: PPByte; ppitch: Pinteger): boolean; stdcall;
procedure DDRAW_Shutdown;
procedure DDRAW_SetPalette( palette: PByteArray);
implementation
uses
Directdraw,
rw_win,
r_main,
rw_imp;
(*
** DDRAW_Init
**
** Builds our DDRAW stuff
*)
type
// TDirectDrawCreate = function(lpGUID: PGUID; out lplpDDRAW: IDirectDraw; pUnkOuter: IUnknown): HResult; cdecl;
// TDirectDrawCreate = function(lpGUID: PGUID; lplpDDRAW: Pointer; pUnkOuter: IUnknown): HResult; cdecl;
TDirectDrawCreate = function(lpGUID : PGUID; out lplpDD : IDirectDraw; pUnkOuter : IUnknown) : HResult; stdcall;
function DDRAW_Init(ppbuffer: PPByte; ppitch: PInteger): boolean; stdcall;
var
QDirectDrawCreate : TDirectDrawCreate;
palentries: array[0..255] of TPALETTEENTRY;
ddrval: HRESULT;
ddsd: TDDSURFACEDESC;
{$IFNDEF DIRECTX_WINDOWMODE}
ddscaps: TDDSCAPS;
{$ENDIF}
i: integer;
begin
ri.Con_Printf(PRINT_ALL, 'Initializing DirectDraw ');
for i := 0 to 255 do
begin
palentries[i].peRed := (d_8to24table[i] shr 0) and $FF;
palentries[i].peGreen := (d_8to24table[i] shr 8) and $FF;
palentries[i].peBlue := (d_8to24table[i] shr 16) and $FF;
end;
(*
** load DLL and fetch pointer to entry point
*)
if (sww_state.hinstDDRAW = 0) then
begin
ri.Con_Printf(PRINT_ALL, '...loading DDRAW.DLL: ');
sww_state.hinstDDRAW := LoadLibrary('ddraw.dll');
if (sww_state.hinstDDRAW = 0) then
begin
ri.Con_Printf(PRINT_ALL, 'failed ');
DDRAW_Shutdown;
result := False;
Exit;
end;
ri.Con_Printf(PRINT_ALL, 'ok ');
end;
QDirectDrawCreate := GetProcAddress(sww_state.hinstDDRAW, 'DirectDrawCreate');
if not (Assigned(QDirectDrawCreate)) then
begin
ri.Con_Printf(PRINT_ALL, '*** DirectDrawCreate = nil *** ');
DDRAW_Shutdown;
result := False;
Exit;
end;
(*
** create the direct draw object
*)
ri.Con_Printf(PRINT_ALL, '...creating DirectDraw object: ');
ddrval := QDirectDrawCreate(nil, sww_state.lpDirectDraw, nil);
if (ddrval <> DD_OK) then
begin
//(*H*) ri.Con_Printf(PRINT_ALL, 'failed - %s ', DDrawError(ddrval));
ri.Con_Printf(PRINT_ALL, 'failed - %s', DDrawError(ddrval));
DDRAW_Shutdown;
result := False;
Exit;
end;
ri.Con_Printf(PRINT_ALL, 'ok ');
(*
** see if linear modes exist first
*)
sww_state.modex := false;
ri.Con_Printf(PRINT_ALL, '...setting exclusive mode: ');
{$IFDEF DIRECTX_WINDOWMODE}
ddrval := sww_state.lpDIRECTDraw.SetCooperativeLevel(sww_state.h_Wnd, DDSCL_NORMAL);
if (ddrval <> DD_OK) then
begin
ri.Con_Printf(PRINT_ALL, 'failed - %s', DDrawError(ddrval));
DDRAW_Shutdown;
result := False;
Exit;
end;
ri.Con_Printf(PRINT_ALL, 'ok ');
(*
** try changing the display mode normally
*)
ri.Con_Printf(PRINT_ALL, '...finding display mode ');
ri.Con_Printf(PRINT_ALL, '...setting linear mode: ');
ddrval := sww_state.lpDIRECTDraw.SetDisplayMode( 1024, 768, 8);
if (ddrval = DD_OK) then
ri.Con_Printf(PRINT_ALL, 'ok ')
else
begin
ri.Con_Printf(PRINT_ALL, 'failed - %s', DDrawError(ddrval));
DDRAW_Shutdown;
result := False;
Exit;
end;
(*
** create our front buffer
*)
FillChar(ddsd, sizeof(ddsd), 0);
ddsd.dwSize := sizeof(ddsd);
ddsd.dwFlags := DDSD_CAPS;
ddsd.ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE;
ri.Con_Printf(PRINT_ALL, '...creating front buffer: ');
ddrval := sww_state.lpDIRECTDraw.CreateSurface(ddsd, sww_state.lpddsFrontBuffer, nil);
if (ddrval <> DD_OK) then
begin
ri.Con_Printf(PRINT_ALL, 'failed - %s', DDrawError(ddrval));
DDRAW_Shutdown;
result := False;
Exit;
end;
ri.Con_Printf(PRINT_ALL, 'ok ');
(*
** create our back buffer
*)
ddsd.ddsCaps.dwCaps := DDSCAPS_BACKBUFFER;
(*
ri.Con_Printf(PRINT_ALL, '...creating back buffer: ');
ddrval := sww_state.lpddsFrontBuffer.GetAttachedSurface(ddsd.ddsCaps, sww_state.lpddsBackBuffer);
if (ddrval <> DD_OK) then
begin
ri.Con_Printf(PRINT_ALL, PChar('failed - '+DDrawError(ddrval)));
DDRAW_Shutdown;
result := False;
Exit;
end;
ri.Con_Printf(PRINT_ALL, 'ok ');
*)
sww_state.lpddsBackBuffer := nil;
// Create clipper
ri.Con_Printf(PRINT_ALL, '...creating clipper: ');
ddrval := sww_state.lpDIRECTDraw.CreateClipper(0, sww_state.lpddsClipper, nil);
if (ddrval <> DD_OK) then
begin
ri.Con_Printf(PRINT_ALL, 'failed - %s', DDrawError(ddrval));
DDRAW_Shutdown;
result := False;
Exit;
end;
ri.Con_Printf(PRINT_ALL, 'ok ');
ri.Con_Printf(PRINT_ALL, '...Attaching clipper to window: ');
ddrval := sww_state.lpddsClipper.SetHWnd(0, sww_state.h_Wnd);
if (ddrval <> DD_OK) then
begin
ri.Con_Printf(PRINT_ALL, 'failed - %s', DDrawError(ddrval));
DDRAW_Shutdown;
result := False;
Exit;
end;
ri.Con_Printf(PRINT_ALL, 'ok ');
ri.Con_Printf(PRINT_ALL, '...Attaching clipper to surface: ');
ddrval := sww_state.lpddsFrontBuffer.SetClipper(sww_state.lpddsClipper);
if (ddrval <> DD_OK) then
begin
ri.Con_Printf(PRINT_ALL, 'failed - %s', DDrawError(ddrval));
DDRAW_Shutdown;
result := False;
Exit;
end;
ri.Con_Printf(PRINT_ALL, 'ok ');
{$ELSE}
ddrval := sww_state.lpDIRECTDraw.SetCooperativeLevel(sww_state.h_Wnd, DDSCL_EXCLUSIVE or DDSCL_FULLSCREEN);
if (ddrval <> DD_OK) then
begin
ri.Con_Printf(PRINT_ALL, 'failed - %s', DDrawError(ddrval));
DDRAW_Shutdown;
result := False;
Exit;
end;
ri.Con_Printf(PRINT_ALL, 'ok ');
(*
** try changing the display mode normally
*)
ri.Con_Printf(PRINT_ALL, '...finding display mode ');
ri.Con_Printf(PRINT_ALL, '...setting linear mode: ');
ddrval := sww_state.lpDIRECTDraw.SetDisplayMode( vid.width, vid.height, 8);
if (ddrval = DD_OK) then
ri.Con_Printf(PRINT_ALL, 'ok ')
(*
** if no linear mode found, go for modex if we're trying 32$240
*)
else
if (sw_mode^.value = 0.0) and (sw_allow_modex^.value <> 0.0) then
begin
ri.Con_Printf(PRINT_ALL, 'failed ');
ri.Con_Printf(PRINT_ALL, '...attempting ModeX 320x240: ');
(*
** reset to normal cooperative level
*)
sww_state.lpDIRECTDraw.SetCooperativeLevel( sww_state.h_Wnd, DDSCL_NORMAL);
(*
** set exclusive mode
*)
ddrval :=
sww_state.lpDIRECTDraw.SetCooperativeLevel( sww_state.h_Wnd,
DDSCL_EXCLUSIVE or
DDSCL_FULLSCREEN or
DDSCL_NOWINDOWCHANGES or
DDSCL_ALLOWMODEX);
if (ddrval <> DD_OK) then
begin
ri.Con_Printf(PRINT_ALL, 'failed - %s', DDrawError(ddrval));
DDRAW_Shutdown;
result := False;
Exit;
end;
(*
** change our display mode
*)
ddrval := sww_state.lpDIRECTDraw.SetDisplayMode( vid.Width, vid.height, 8);
if (ddrval <> DD_OK) then
begin
ri.Con_Printf(PRINT_ALL, 'failed - %s', DDrawError(ddrval));
DDRAW_Shutdown;
result := False;
Exit;
end;
ri.Con_Printf(PRINT_ALL, 'ok ');
sww_state.modex := true;
end
else
begin
ri.Con_Printf(PRINT_ALL, 'failed ');
DDRAW_Shutdown;
result := False;
Exit;
end;
(*
** create our front buffer
*)
FillChar(ddsd, sizeof(ddsd), 0);
ddsd.dwSize := sizeof(ddsd);
ddsd.dwFlags := DDSD_CAPS or DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE or DDSCAPS_FLIP or DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount := 1;
ri.Con_Printf(PRINT_ALL, '...creating front buffer: ');
ddrval := sww_state.lpDIRECTDraw.CreateSurface(ddsd, sww_state.lpddsFrontBuffer, nil);
if (ddrval <> DD_OK) then
begin
ri.Con_Printf(PRINT_ALL, 'failed - %s', DDrawError(ddrval));
DDRAW_Shutdown;
result := False;
Exit;
end;
ri.Con_Printf(PRINT_ALL, 'ok ');
(*
** see if we're a ModeX mode
*)
sww_state.lpddsFrontBuffer.GetCaps(ddscaps);
if (ddscaps.dwCaps and DDSCAPS_MODEX) = 0 then
ri.Con_Printf(PRINT_ALL, '...using ModeX ');
(*
** create our back buffer
*)
ddsd.ddsCaps.dwCaps := DDSCAPS_BACKBUFFER;
ri.Con_Printf(PRINT_ALL, '...creating back buffer: ');
ddrval := sww_state.lpddsFrontBuffer.GetAttachedSurface(ddsd.ddsCaps, sww_state.lpddsBackBuffer);
if (ddrval <> DD_OK) then
begin
ri.Con_Printf(PRINT_ALL, 'failed - %s', DDrawError(ddrval));
DDRAW_Shutdown;
result := False;
Exit;
end;
ri.Con_Printf(PRINT_ALL, 'ok ');
{$ENDIF}
(*
** create our rendering buffer
*)
FillChar(ddsd, sizeof(ddsd), 0);
ddsd.dwSize := sizeof(ddsd);
ddsd.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS;
ddsd.dwHeight := vid.height;
ddsd.dwWidth := vid.width;
ddsd.ddsCaps.dwCaps := DDSCAPS_OFFSCREENPLAIN or DDSCAPS_SYSTEMMEMORY;
ri.Con_Printf(PRINT_ALL, '...creating offscreen buffer: ');
ddrval := sww_state.lpDIRECTDraw.CreateSurface(ddsd,sww_state.lpddsOffScreenBuffer, nil);
if (ddrval <> DD_OK) then
begin
ri.Con_Printf(PRINT_ALL, 'failed - %s', DDrawError(ddrval));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -