⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r_surf.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
// PLEASE, don't modify this file
// 50% complete

{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): r_surf.c: surface-related refresh code                            }
{                                                                            }
{ Initial conversion by : YgriK (Igor Karpov) - glYgriK@hotbox.ru            }
{ Initial conversion on : 04-Feb-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:                               }
{ x)                                                                         }
{                                                                            }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{ 1) Do more tests                                                           }
{                                                                            }
{----------------------------------------------------------------------------}

// r_surf.c: surface-related refresh code

unit r_surf;

interface

uses
  q_shared,
  r_model,
  r_local;

procedure D_FlushCaches;
procedure R_SurfacePatch;
procedure R_InitCaches;
function R_TextureAnimation(tex: mtexinfo_p): image_p;
procedure R_DrawSurface;
function D_CacheSurface(surface: msurface_p; miplevel: Integer): surfcache_p;

var
  r_drawsurf: drawsurf_t;
  sc_size: Integer;
  sc_rover: surfcache_p;
  sc_base: surfcache_p;

implementation

uses
  r_bsp_c,
  r_light,
  r_main,
  r_misc,
  ref,
  SysUtils;

procedure R_DrawSurfaceBlock8_mip0; forward;
procedure R_DrawSurfaceBlock8_mip1; forward;
procedure R_DrawSurfaceBlock8_mip2; forward;
procedure R_DrawSurfaceBlock8_mip3; forward;

var
surfmiptable: array[0..3]

of procedure = (
  R_DrawSurfaceBlock8_mip0,
  R_DrawSurfaceBlock8_mip1,
  R_DrawSurfaceBlock8_mip2,
  R_DrawSurfaceBlock8_mip3
  );
//*****************************************
// CodeFusion: Has been commented because
//   it's not used in pure delphi version.
//*****************************************
//  sourcesstep     : Integer;
//  lightdelta      : Integer;
//  lightdeltastep  : Integer;
//*****************************************
var
  lightleft: Integer;
  blocksize: Integer;
  sourcetstep: Integer;
  lightright: Integer;
  lightleftstep: Integer;
  lightrightstep: Integer;
  blockdivshift: Integer;
  blockdivmask: Cardinal;
  prowdestbase: Pointer;
  pbasesource: PByte;
  surfrowbytes: Integer; // used by ASM files
  r_lightptr: PCardinal;
  r_stepback: Integer;
  r_lightwidth: Integer;
  r_numhblocks: Integer;
  r_numvblocks: Integer;
  r_source: PByte;
  r_sourcemax: PByte;

//extern	unsigned		blocklights[1024];	// allow some very large lightmaps

  surfscale: Single;
  r_cache_thrash: qboolean; // set if surface cache is thrashing

(*
===============
R_TextureAnimation

Returns the proper texture for a given time and base texture
===============
*)

  function R_TextureAnimation(tex: mtexinfo_p): image_p;
  var
    c: Integer;
  begin
    if (tex^.next = nil) then
    begin
      Result := tex^.image;
      Exit;
    end;
    c := currententity^.frame mod tex^.numframes;
    while (c > 0) do
    begin
      tex := tex^.next;
      Dec(c);
    end;
    Result := tex^.image;
  end;

(*
===============
R_DrawSurface
===============
*)

  procedure R_DrawSurface;
  var
    basetptr: PByte;
    smax, tmax: Integer;
    twidth, u: Integer;
    soffset: Integer;
    basetoffset: Integer;
    texwidth: Integer;
    horzblockstep: Integer;
    pcolumndest: PByte;
    pblockdrawer: procedure;
    mt: image_p;
  begin
    surfrowbytes := r_drawsurf.rowbytes;
    mt := r_drawsurf.image;

    r_source := mt^.pixels[r_drawsurf.surfmip];

// the fractional light values should range from 0 to (VID_GRADES - 1) << 16
// from a source range of 0 - 255

    texwidth := mt^.width shr r_drawsurf.surfmip;

    blocksize := 16 shr r_drawsurf.surfmip;
    blockdivshift := 4 - r_drawsurf.surfmip;
    blockdivmask := (1 shl blockdivshift) - 1;

    r_lightwidth := _SAR(r_drawsurf.surf^.extents[0], 4) + 1;

    r_numhblocks := r_drawsurf.surfwidth shr blockdivshift;
    r_numvblocks := r_drawsurf.surfheight shr blockdivshift;

//==============================

    pblockdrawer := surfmiptable[r_drawsurf.surfmip];
// TODO: only needs to be set when there is a display settings change
    horzblockstep := blocksize;

    smax := mt^.width shr r_drawsurf.surfmip;
    twidth := texwidth;
    tmax := mt^.height shr r_drawsurf.surfmip;
    sourcetstep := texwidth;
    r_stepback := tmax * twidth;

    r_sourcemax := PByte(Integer(r_source) + (tmax * smax));

    soffset := r_drawsurf.surf^.texturemins[0];
    basetoffset := r_drawsurf.surf^.texturemins[1];

// << 16 components are to guarantee positive values for %
    soffset := (_SAR(soffset, r_drawsurf.surfmip) + _SAR(smax, 16)) mod smax;
    basetptr := @PByteArray(r_source)^[(((_SAR(basetoffset, r_drawsurf.surfmip) + _SAR(tmax, 16)) mod tmax) * twidth)];

    pcolumndest := r_drawsurf.surfdat;

    for u := 0 to r_numhblocks - 1 do
    begin
      r_lightptr := PCardinal(Integer(@blocklights) + (u * SizeOf(Cardinal)));
      prowdestbase := pcolumndest;

      pbasesource := PByte(Integer(basetptr) + soffset);

      pblockdrawer;

      soffset := soffset + blocksize;
      if (soffset >= smax) then
        soffset := 0;

      Inc(Integer(pcolumndest), horzblockstep);
    end;
  end;

//=============================================================================

{$IFNDEF id386}

(*
================
R_DrawSurfaceBlock8_mip0
================
*)

  procedure R_DrawSurfaceBlock8_mip0;
  var
    v, i, b: Integer;
    lightstep: Integer;
    lighttemp: Integer;
    light: Integer;
    pix: Byte;
    psource: PByte;
    prowdest: PByte;
  begin
    psource := pbasesource;
    prowdest := prowdestbase;

    for V := 0 to r_numvblocks - 1 do
    begin
 // FIXME: make these locals?
 // FIXME: use delta rather than both right and left, like ASM?
      lightleft := r_lightptr^;
      lightright := PCardinal(Integer(r_lightptr) + SizeOf(Cardinal))^;
      Inc(Integer(r_lightptr), r_lightwidth * SizeOf(Cardinal));
      lightleftstep := _SAR(Integer(r_lightptr^) - lightleft, 4);
      lightrightstep := _SAR(Integer(PCardinal(Integer(r_lightptr) + SizeOf(Cardinal))^) - lightright, 4);

      for i := 0 to 15 do
      begin
        lighttemp := lightleft - lightright;
        lightstep := _SAR(lighttemp, 4);

        light := lightright;

        for b := 15 downto 0 do
        begin
          pix := PByteArray(psource)^[b];
          PByteArray(prowdest)^[b] := PByteArray(vid.colormap)^[(light and $FF00) + pix];
          Inc(light, lightstep);
        end;

        Inc(Integer(psource), sourcetstep);
        Inc(lightright, lightrightstep);
        Inc(lightleft, lightleftstep);
        Inc(Integer(prowdest), surfrowbytes);
      end;

      if (Integer(psource) >= Integer(r_sourcemax)) then
        Dec(Integer(psource), r_stepback);
    end;
  end;

(*
================
R_DrawSurfaceBlock8_mip1
================
*)

  procedure R_DrawSurfaceBlock8_mip1;
  var
    v, i, b: Integer;
    lightstep: Integer;
    lighttemp: Integer;
    light: Integer;
    pix: Byte;
    psource: PByte;
    prowdest: PByte;
  begin
    psource := pbasesource;
    prowdest := prowdestbase;

    for V := 0 to r_numvblocks - 1 do
    begin
 // FIXME: make these locals?
 // FIXME: use delta rather than both right and left, like ASM?
      lightleft := r_lightptr^;
      lightright := PCardinal(Integer(r_lightptr) + SizeOf(Cardinal))^;
      Inc(Integer(r_lightptr), r_lightwidth * SizeOf(Cardinal));
      lightleftstep := _SAR(Integer(r_lightptr^) - lightleft, 3);
      lightrightstep := _SAR(Integer(PCardinal(Integer(r_lightptr) + SizeOf(Cardinal))^) - lightright, 3);

      for i := 0 to 7 do
      begin
        lighttemp := lightleft - lightright;
        lightstep := _SAR(lighttemp, 3);

        light := lightright;

        for b := 7 downto 0 do
        begin
          pix := PByteArray(psource)^[b];
          PByteArray(prowdest)^[b] := PByteArray(vid.colormap)^[(light and $FF00) + pix];
          Inc(light, lightstep);
        end;

        Inc(Integer(psource), sourcetstep);
        Inc(lightright, lightrightstep);
        Inc(lightleft, lightleftstep);
        Inc(Integer(prowdest), surfrowbytes);
      end;

      if (Integer(psource) >= Integer(r_sourcemax)) then
        Dec(Integer(psource), r_stepback);
    end;
  end;

(*
================
R_DrawSurfaceBlock8_mip2
================
*)

  procedure R_DrawSurfaceBlock8_mip2;
  var
    v, i, b: Integer;
    lightstep: Integer;
    lighttemp: Integer;
    light: Integer;
    pix: Byte;
    psource: PByte;
    prowdest: PByte;
  begin
    psource := pbasesource;
    prowdest := prowdestbase;

    for V := 0 to r_numvblocks - 1 do
    begin
 // FIXME: make these locals?
 // FIXME: use delta rather than both right and left, like ASM?
      lightleft := r_lightptr^;
      lightright := PCardinal(Integer(r_lightptr) + SizeOf(Cardinal))^;
      Inc(Integer(r_lightptr), r_lightwidth * SizeOf(Cardinal));
      lightleftstep := _SAR(Integer(r_lightptr^) - lightleft, 2);
      lightrightstep := _SAR(Integer(PCardinal(Integer(r_lightptr) + SizeOf(Cardinal))^) - lightright, 2);

      for i := 0 to 3 do
      begin
        lighttemp := lightleft - lightright;
        lightstep := _SAR(lighttemp, 2);

        light := lightright;

        for b := 3 downto 0 do
        begin
          pix := PByteArray(psource)^[b];
          PByteArray(prowdest)^[b] := PByteArray(vid.colormap)^[(light and $FF00) + pix];
          Inc(light, lightstep);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -