📄 r_poly.pas
字号:
{$ALIGN 8}{$MINENUMSIZE 4}
{----------------------------------------------------------------------------}
{ }
{ File(s): r_poly.pas }
{ }
{ Initial conversion by : Jose M. Navarro (jose.man@airtel.net) }
{ Initial conversion on : 16-Jul-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 puC:\Documents and Settings\PCDELPHI4.PC-DELPHI4\Escritorio\g_target.c }
{ blished 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 : 12-Aug-2002 }
{ Updated by : CodeFusion (Michael@Skovslund.dk) }
{ }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on: }
{ All critical points has been noted with //????. Please search that in }
{ final conversion }
{ }
{ r_scan.pas unit must be included (interface) when finished. }
{ r_main.pas unit must be included (implementation) when finished }
{ For uncomment when r_main.pas included. }
{ Sys_Error (in ref.pas) still doesn't support arguments }
{ no overloaded version of VectorSubtract }
{ mSurface_s structure hasn't any field called "nextalphasurface" }
{ DotProduct expects vec3_t instead vec5_t }
{ }
{----------------------------------------------------------------------------}
{ * TODO: }
{----------------------------------------------------------------------------}
unit r_poly;
interface
uses
r_local,
r_model,
q_shared;
procedure R_DrawSpanletOpaque; cdecl;
procedure R_DrawSpanletTurbulentStipple33; cdecl;
procedure R_DrawSpanletTurbulentStipple66; cdecl;
procedure R_DrawSpanletTurbulentBlended66; cdecl;
procedure R_DrawSpanletTurbulentBlended33; cdecl;
procedure R_DrawSpanlet33; cdecl;
procedure R_DrawSpanletConstant33; cdecl;
procedure R_DrawSpanlet66; cdecl;
procedure R_DrawSpanlet33Stipple; cdecl;
procedure R_DrawSpanlet66Stipple; cdecl;
function R_ClipPolyFace(nump: Integer; pclipplane: clipplane_p): Integer;
procedure R_PolygonDrawSpans(pspan: espan_p; iswater: Integer);
procedure R_PolygonScanLeftEdge;
procedure R_PolygonScanRightEdge;
procedure R_ClipAndDrawPoly(alpha: Single; isturbulent: Integer; textured: qboolean);
procedure R_BuildPolygonFromSurface(fa: msurface_p);
procedure R_PolygonCalculateGradients;
procedure R_DrawPoly(iswater: Integer);
procedure R_DrawAlphaSurfaces;
procedure R_IMFlatShadedQuad(a: vec3_t; b: vec3_t; c: vec3_t; d: vec3_t; color: Integer; alpha: Single);
var
r_alpha_surfaces: msurface_p;
r_polydesc: polydesc_t;
r_clip_verts: array[0..1, 0..(MAXWORKINGVERTS + 2) - 1] of vec5_t;
implementation
uses
r_surf,
r_misc,
r_main,
r_scan,
r_rast,
r_bsp_c,
SysUtils,
DelphiTypes,
Math;
const
AFFINE_SPANLET_SIZE = 16;
AFFINE_SPANLET_SIZE_BITS = 4;
type
spanletvars_p = ^spanletvars_t;
spanletvars_t = record
pbase: PByte;
pdest: PByte;
pz: PSmallInt;
s, t: fixed16_t;
sstep: fixed16_t;
tstep: fixed16_t;
izi: Integer;
izistep: Integer;
izistep_times_2: Integer;
spancount: Integer;
u, v: Cardinal;
end;
var
s_spanletvars: spanletvars_t;
r_polyblendcolor: Integer;
s_polygon_spans: espan_p;
clip_current: Integer;
s_minindex: Integer;
s_maxindex: Integer;
{
** R_DrawSpanletOpaque
}
procedure R_DrawSpanletOpaque;
var
btemp: cardinal; // translated unsigned as cardinal
ts, tt: Integer;
begin
repeat
ts := _SAR(s_spanletvars.s, 16);
tt := _SAR(s_spanletvars.t, 16);
btemp := PByte(Integer(s_spanletvars.pbase) + (ts) + (tt) * cachewidth)^;
if btemp <> 255 then
begin
if s_spanletvars.pz^ <= _SAR(s_spanletvars.izi, 16) then
begin
s_spanletvars.pz^ := _SAR(s_spanletvars.izi, 16);
s_spanletvars.pdest^ := btemp;
end;
end;
Inc(s_spanletvars.izi, s_spanletvars.izistep);
Inc(Integer(s_spanletvars.pdest), 1);
Inc(Integer(s_spanletvars.pz), SizeOf(SmallInt));
Inc(s_spanletvars.s, s_spanletvars.sstep);
Inc(s_spanletvars.t, s_spanletvars.tstep);
Dec(s_spanletvars.spancount); // extracted from while part
until (s_spanletvars.spancount <= 0); // negated condition for until loop
end;
{
** R_DrawSpanletTurbulentStipple33
}
procedure R_DrawSpanletTurbulentStipple33;
var
btemp: Cardinal;
sturb: Integer;
tturb: Integer;
pdest: PByte;
pz: PSmallInt;
izi: Integer;
begin
pdest := s_spanletvars.pdest;
pz := s_spanletvars.pz;
izi := s_spanletvars.izi;
if (s_spanletvars.v and 1) <> 0 then
begin
Inc(Integer(s_spanletvars.pdest), s_spanletvars.spancount);
Inc(Integer(s_spanletvars.pz), s_spanletvars.spancount * SizeOf(SmallInt));
if s_spanletvars.spancount = AFFINE_SPANLET_SIZE then
Inc(s_spanletvars.izi, _SAL(s_spanletvars.izistep, AFFINE_SPANLET_SIZE_BITS))
else
Inc(s_spanletvars.izi, s_spanletvars.izistep * s_spanletvars.izistep);
if (s_spanletvars.u and 1) <> 0 then
begin
Inc(izi, s_spanletvars.izistep);
Inc(s_spanletvars.s, s_spanletvars.sstep);
Inc(s_spanletvars.t, s_spanletvars.tstep);
Inc(Integer(pdest), 1);
Inc(Integer(pz), SizeOf(SmallInt));
Dec(s_spanletvars.spancount);
end;
s_spanletvars.sstep := s_spanletvars.sstep * 2;
s_spanletvars.tstep := s_spanletvars.tstep * 2;
while (s_spanletvars.spancount > 0) do
begin
// temporary conversion for pointer arithmetic
// tmp := r_turb_turb;
sturb := _SAR(PIntegerArray(r_turb_turb)^[_SAR(s_spanletvars.t, 16) and (CYCLE - 1)], 16) and 63;
tturb := _SAR(PIntegerArray(r_turb_turb)^[_SAR(s_spanletvars.s, 16) and (CYCLE - 1)], 16) and 63;
btemp := PByte(Integer(s_spanletvars.pbase) + (sturb) + _SAL(tturb, 6))^;
if pz^ <= _SAR(izi, 16) then
pdest^ := btemp;
Inc(izi, s_spanletvars.izistep_times_2);
Inc(s_spanletvars.s, s_spanletvars.sstep);
Inc(s_spanletvars.t, s_spanletvars.tstep);
Inc(Integer(pdest), 2);
Inc(Integer(pz), 2 * SizeOF(SmallInt));
Dec(s_spanletvars.spancount, 2);
end;
end;
end;
{
** R_DrawSpanletTurbulentStipple66
}
procedure R_DrawSpanletTurbulentStipple66;
var
btemp: cardinal;
sturb, tturb: integer;
pdest: PByte;
pz: PSmallInt;
izi: integer;
tmp: PInteger;
begin
pdest := s_spanletvars.pdest;
pz := s_spanletvars.pz;
izi := s_spanletvars.izi;
if (s_spanletvars.v and 1) = 0 then
begin
Inc(Integer(s_spanletvars.pdest), s_spanletvars.spancount);
Inc(Integer(s_spanletvars.pz), s_spanletvars.spancount * SizeOf(SmallInt));
if s_spanletvars.spancount = AFFINE_SPANLET_SIZE then
Inc(s_spanletvars.izi, s_spanletvars.izistep shl AFFINE_SPANLET_SIZE_BITS)
else
Inc(s_spanletvars.izi, s_spanletvars.izistep * s_spanletvars.izistep);
if (s_spanletvars.u and 1) <> 0 then
begin
Inc(izi, s_spanletvars.izistep);
Inc(s_spanletvars.s, s_spanletvars.sstep);
Inc(s_spanletvars.t, s_spanletvars.tstep);
Inc(Integer(pdest));
Inc(Integer(pz), SizeOf(SmallInt));
Dec(s_spanletvars.spancount);
end;
s_spanletvars.sstep := s_spanletvars.sstep * 2;
s_spanletvars.tstep := s_spanletvars.tstep * 2;
while s_spanletvars.spancount > 0 do
begin
// temporary conversion for pointer arithmetic
tmp := r_turb_turb;
Inc(Integer(tmp), ((s_spanletvars.t shr 16) and (CYCLE - 1)) * SizeOf(Integer));
sturb := ((s_spanletvars.s + tmp^) shr 16) and 63;
// temporary conversion for pointer arithmetic
tmp := r_turb_turb;
Inc(Integer(tmp), ((s_spanletvars.s shr 16) and (CYCLE - 1)) * SizeOf(Integer));
tturb := ((s_spanletvars.t + tmp^) shr 16) and 63;
btemp := PByte(Integer(s_spanletvars.pbase) + (sturb) + (tturb shl 6))^;
if pz^ <= (izi shr 16) then
pdest^ := btemp;
Inc(izi, s_spanletvars.izistep_times_2);
Inc(s_spanletvars.s, s_spanletvars.sstep);
Inc(s_spanletvars.t, s_spanletvars.tstep);
Inc(Integer(pdest), 2);
Inc(Integer(pz), 2 * SizeOf(SmallInt));
Dec(s_spanletvars.spancount, 2);
end;
end
else
begin
Inc(Integer(s_spanletvars.pdest), s_spanletvars.spancount);
Inc(Integer(s_spanletvars.pz), s_spanletvars.spancount * SizeOf(SmallInt));
if s_spanletvars.spancount = AFFINE_SPANLET_SIZE then
Inc(s_spanletvars.izi, s_spanletvars.izistep shl AFFINE_SPANLET_SIZE_BITS)
else
Inc(s_spanletvars.izi, s_spanletvars.izistep * s_spanletvars.izistep);
while s_spanletvars.spancount > 0 do
begin
// temporary conversion for pointer arithmetic
tmp := r_turb_turb;
Inc(Integer(tmp), ((s_spanletvars.t shr 16) and (CYCLE - 1)) * SizeOf(Integer));
sturb := ((s_spanletvars.s + tmp^) shr 16) and 63;
// temporary conversion for pointer arithmetic
tmp := r_turb_turb;
Inc(Integer(tmp), ((s_spanletvars.s shr 16) and (CYCLE - 1)) * SizeOf(Integer));
tturb := ((s_spanletvars.t + tmp^) shr 16) and 63;
btemp := PByte(Integer(s_spanletvars.pbase) + (sturb) + (tturb shl 6))^;
if pz^ <= (izi shr 16) then
pdest^ := btemp;
Inc(izi, s_spanletvars.izistep);
Inc(s_spanletvars.s, s_spanletvars.sstep);
Inc(s_spanletvars.t, s_spanletvars.tstep);
Inc(Integer(pdest));
Inc(Integer(pz), SizeOf(SmallInt));
Dec(s_spanletvars.spancount);
end;
end;
end;
{
** R_DrawSpanletTurbulentBlended
}
procedure R_DrawSpanletTurbulentBlended66;
var
btemp: cardinal;
sturb, tturb: integer;
tmp: PInteger;
tmp_b: PByte;
begin
repeat
// temporary conversion for pointer arithmetic
tmp := r_turb_turb;
Inc(Integer(tmp), ((s_spanletvars.t shr 16) and (CYCLE - 1)) * SizeOf(Integer));
sturb := ((s_spanletvars.s + tmp^) shr 16) and 63;
// temporary conversion for pointer arithmetic
tmp := r_turb_turb;
Inc(Integer(tmp), ((s_spanletvars.s shr 16) and (CYCLE - 1)) * SizeOf(Integer));
tturb := ((s_spanletvars.t + tmp^) shr 16) and 63;
btemp := PByte(Integer(s_spanletvars.pbase) + (sturb) + (tturb shl 6))^;
if s_spanletvars.pz^ <= (s_spanletvars.izi shr 16) then
begin
// temporary conversion for pointer arithmetic
tmp_b := vid.alphamap;
Inc(Integer(tmp_b), btemp * 256 + s_spanletvars.pdest^);
s_spanletvars.pdest^ := tmp_b^;
end;
Inc(s_spanletvars.izi, s_spanletvars.izistep);
Inc(Integer(s_spanletvars.pdest));
Inc(Integer(s_spanletvars.pz), SizeOf(SmallInt));
Inc(s_spanletvars.s, s_spanletvars.sstep);
Inc(s_spanletvars.t, s_spanletvars.tstep);
Dec(s_spanletvars.spancount);
until (s_spanletvars.spancount <= 0);
end;
procedure R_DrawSpanletTurbulentBlended33;
var
btemp: cardinal;
sturb, tturb: integer;
tmp: PInteger;
tmp_b: PByte;
begin
repeat
// temporary conversion for pointer arithmetic
tmp := r_turb_turb;
Inc(tmp, (s_spanletvars.t shr 16) and (CYCLE - 1));
sturb := ((s_spanletvars.s + tmp^) shr 16) and 63;
// temporary conversion for pointer arithmetic
tmp := r_turb_turb;
Inc(tmp, (s_spanletvars.s shr 16) and (CYCLE - 1));
tturb := ((s_spanletvars.t + tmp^) shr 16) and 63;
btemp := PByte(Integer(s_spanletvars.pbase) + (sturb) + (tturb shl 6))^;
if s_spanletvars.pz^ <= (s_spanletvars.izi shr 16) then
begin
// temporary conversion for pointer arithmetic
tmp_b := vid.alphamap;
Inc(Integer(tmp_b), btemp + s_spanletvars.pdest^ * 256);
s_spanletvars.pdest^ := tmp_b^;
end;
Inc(s_spanletvars.izi, s_spanletvars.izistep);
Inc(Integer(s_spanletvars.pdest), 1);
Inc(Integer(s_spanletvars.pz), SizeOf(SmallInt));
Inc(s_spanletvars.s, s_spanletvars.sstep);
Inc(s_spanletvars.t, s_spanletvars.tstep);
Dec(s_spanletvars.spancount);
until not (s_spanletvars.spancount > 0);
end;
{
** R_DrawSpanlet33
}
procedure R_DrawSpanlet33;
var
btemp: cardinal;
ts, tt: Integer;
tmp_b: PByte;
begin
repeat
ts := _SAR(s_spanletvars.s, 16);
tt := _SAR(s_spanletvars.t, 16);
btemp := PByte(Integer(s_spanletvars.pbase) + (ts) + (tt) * cachewidth)^;
if btemp <> 255 then
begin
if s_spanletvars.pz^ <= _SAR(s_spanletvars.izi, 16) then
begin
// temporary conversion for pointer arithmetic
tmp_b := vid.alphamap;
Inc(Integer(tmp_b), btemp + s_spanletvars.pdest^ * 256);
s_spanletvars.pdest^ := tmp_b^;
end;
end;
Inc(s_spanletvars.izi, s_spanletvars.izistep);
Inc(Integer(s_spanletvars.pdest), 1);
Inc(Integer(s_spanletvars.pz), SizeOf(SmallInt));
Inc(s_spanletvars.s, s_spanletvars.sstep);
Inc(s_spanletvars.t, s_spanletvars.tstep);
Dec(s_spanletvars.spancount);
until not (s_spanletvars.spancount > 0);
end;
procedure R_DrawSpanletConstant33;
var
tmp_b: PByte;
begin
repeat
if s_spanletvars.pz^ <= _SAR(s_spanletvars.izi, 16) then
begin
// temporary conversion for pointer arithmetic
tmp_b := vid.alphamap;
Inc(Integer(tmp_b), r_polyblendcolor + s_spanletvars.pdest^ * 256);
s_spanletvars.pdest^ := tmp_b^;
end;
Inc(s_spanletvars.izi, s_spanletvars.izistep);
Inc(Integer(s_spanletvars.pdest), 1);
Inc(Integer(s_spanletvars.pz), SizeOf(SmallInt));
Dec(s_spanletvars.spancount);
until not (s_spanletvars.spancount > 0);
end;
{
** R_DrawSpanlet66
}
procedure R_DrawSpanlet66;
var
btemp: cardinal;
ts, tt: Integer;
tmp_b: PByte;
begin
repeat
ts := _SAR(s_spanletvars.s, 16);
tt := _SAR(s_spanletvars.t, 16);
btemp := PByte(Integer(s_spanletvars.pbase) + (ts) + (tt) * cachewidth)^;
if btemp <> 255 then
begin
if s_spanletvars.pz^ <= _SAR(s_spanletvars.izi, 16) then
begin
// temporary conversion for pointer arithmetic
tmp_b := vid.alphamap;
Inc(Integer(tmp_b), btemp * 256 + s_spanletvars.pdest^);
s_spanletvars.pdest^ := tmp_b^;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -