📄 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 : }
{ Updated by : }
{ }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on: }
{ 1) ? }
{----------------------------------------------------------------------------}
{ * TODO: }
{ 1) ? }
{----------------------------------------------------------------------------}
unit rw_ddraw;
interface
uses
Windows,
SysUtils,
r_local;
var
d_8to24table: array[0..255] of Word;
function DDrawError(code: integer): string;
function DDRAW_Init(ppbuffer: PByte; ppitch: Pinteger): Boolean; //qboolean;
procedure DDRAW_Shutdown;
procedure DDRAW_SetPalette( palette: PByteArray);
implementation
uses Directdraw,
rw_win;
(*
** DDRAW_Init
**
** Builds our DDRAW stuff
*)
function DDRAW_Init(ppbuffer: PByte; ppitch: Pinteger): Boolean; //qboolean;
var
ddrval: HRESULT;
ddsd: TDDSURFACEDESC;
ddscaps: TDDSCAPS;
palentries: array[0..255] of TPALETTEENTRY;
i: integer;
sw_allow_modex: PChar;
QDirectDrawCreate: function(lpGUID: PGUID; lplpDDRAW: IDIRECTDRAW; pUnkOuter:
IUnknown): Hresult;
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 not (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 (QDirectDrawCreate = nil) 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
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: ');
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) and sw_allow_modex.value) 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 SCL - %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 SDM - %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 ');
(*
** 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));
DDRAW_Shutdown;
result := False;
Exit;
end;
ri.Con_Printf(PRINT_ALL, 'ok ');
(*
** create our DIRECTDRAWPALETTE
*)
ri.Con_Printf(PRINT_ALL, '...creating palette: ');
ddrval := sww_state.lpDIRECTDraw.CreatePalette( DDPCAPS_8BIT or DDPCAPS_ALLOW256, @palentries,
sww_state.lpddpPalette,
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, '...setting palette: ');
ddrval :=
sww_state.lpddsFrontBuffer.SetPalette( sww_state.lpddpPalette);
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 ');
DDRAW_SetPalette(@sw_state.currentpalette);
(*
** lock the back buffer
*)
FillChar(ddsd, sizeof(ddsd), 0);
ddsd.dwSize := sizeof(ddsd);
ri.Con_Printf(PRINT_ALL, '...locking backbuffer: ');
ddrval :=
sww_state.lpddsOffScreenBuffer.Lock( nil, ddsd, DDLOCK_WAIT, 0);
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 ');
ppbuffer := @(ddsd.lpSurface);
ppitch^ := ddsd.lPitch;
for i := 0 to vid.height - 1 do
begin
Inc( ppbuffer, (i * ppitch^) );
FillChar(ppbuffer , sizeof(ppitch), 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -