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

📄 r_surf.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
        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_mip3
================
*)

  procedure R_DrawSurfaceBlock8_mip3;
  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, 1);
      lightrightstep := _SAR(Integer(PCardinal(Integer(r_lightptr) + SizeOf(Cardinal))^) - lightright, 1);

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

        light := lightright;

        for b := 1 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;
{$ENDIF}

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

(*
================
R_InitCaches

================
*)
procedure R_InitCaches;
var
	size  : Integer;
	pix   : Integer;
begin
	// calculate size to allocate
	if (sw_surfcacheoverride^.value <> 0.0) then
	begin
		size := Trunc(sw_surfcacheoverride^.value);
	end
	else
	begin
		size := SURFCACHE_SIZE_AT_320X240;

		pix := vid.width*vid.height;
		if (pix > 64000) then
			Inc(size, (pix-64000)*3);
	end;

	// round up to page size
	size := (size + 8191) and (not 8191);

	ri.Con_Printf(PRINT_ALL,'%dk surface cache', (size shr 10));

	sc_size := size;
	sc_base := AllocMem(size);
	sc_rover := sc_base;

	sc_base^.next := NIL;
	sc_base^.owner := NIL;
	sc_base^.size := sc_size;
end;

(*
==================
D_FlushCaches
==================
*)

  procedure D_FlushCaches;
  var
    c: surfcache_p;
  begin
    if (sc_base = nil) then
      Exit;

    c := sc_base;
    while (c <> nil) do
    begin
      if (c^.owner <> nil) then
        c^.owner^ := nil;
      c := c^.next
    end;

    sc_rover := sc_base;
    sc_base^.next := nil;
    sc_base^.owner := nil;
    sc_base^.size := sc_size;
  end;

(*
=================
D_SCAlloc
=================
*)

  function D_SCAlloc(width, size: Integer): surfcache_p;
  var
    new: surfcache_p;
    wrapped_this_time: qboolean;
  begin
    if ((width < 0) or (width > 256)) then
      ri.Sys_Error(ERR_FATAL, PChar('D_SCAlloc: bad cache width ' + IntToStr(width)));

    if ((size <= 0) or (size > $10000)) then
      ri.Sys_Error(ERR_FATAL, PChar('D_SCAlloc: bad cache size ' + IntToStr(size)));

// Don't know if this generates an error but lets see :-)
    size := Integer(@(surfcache_p(0)^.data[size]));
    size := (size + 3) and (not 3);
    if (size > sc_size) then
      ri.Sys_Error(ERR_FATAL, PChar('D_SCAlloc: ' + IntToStr(size) + ' > cache size of ' + IntToStr(sc_size)));

// if there is not size bytes after the rover, reset to the start
    wrapped_this_time := false;

    if (sc_rover = nil) or ((Integer(sc_rover) - Integer(sc_base)) > sc_size - size) then
    begin
      if (sc_rover <> nil) then
      begin
        wrapped_this_time := true;
      end;
      sc_rover := sc_base;
    end;

// colect and free surfcache_t blocks until the rover block is large enough
    new := sc_rover;
    if (sc_rover^.owner <> nil) then
      sc_rover^.owner^ := nil;

    while (new^.size < size) do
    begin
 // free another
      sc_rover := sc_rover^.next;
      if (sc_rover = nil) then
        ri.Sys_Error(ERR_FATAL, 'D_SCAlloc: hit the end of memory');
      if (sc_rover^.owner <> nil) then
        sc_rover^.owner^ := nil;

      Inc(new^.size, sc_rover^.size);
      new^.next := sc_rover^.next;
    end;

// create a fragment out of any leftovers
    if (new^.size - size > 256) then
    begin
      sc_rover := surfcache_p(Integer(new) + size);
      sc_rover^.size := new^.size - size;
      sc_rover^.next := new^.next;
      sc_rover^.width := 0;
      sc_rover^.owner := nil;
      new^.next := sc_rover;
      new^.size := size;
    end
    else
      sc_rover := new^.next;

    new^.width := width;
// DEBUG
    if (width > 0) then
      new^.height := (size - sizeof(new^) + sizeof(new^.data)) div width;

    new^.owner := nil; // should be set properly after return

    if (d_roverwrapped) then
    begin
      if (wrapped_this_time or (Integer(sc_rover) >= Integer(d_initial_rover))) then
        r_cache_thrash := true;
    end
    else
    begin
      if (wrapped_this_time) then
      begin
        d_roverwrapped := true;
      end;
    end;
    Result := new;
  end;

(*
=================
D_SCDump
=================
*)
procedure D_SCDump;
var
  test  : surfcache_p;
begin
  test := sc_base;
  while (test <> nil) do
	begin
		if (Integer(test) = Integer(sc_rover)) then
			ri.Con_Printf(PRINT_ALL,'ROVER:');
		ri.Con_Printf(PRINT_ALL,'%d : %d bytes. %d width', Integer(test), test^.size, test^.width);
    test := test^.next;
	end;
end;

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

// if the num is not a power of 2, assume it will not repeat

  function MaskForNum(num: Integer): Integer;
  begin
    if (num = 128) then
    begin
      Result := 127;
      Exit;
    end;
    if (num = 64) then
    begin
      Result := 63;
      Exit;
    end;
    if (num = 32) then
    begin
      Result := 31;
      Exit;
    end;
    if (num = 16) then
    begin
      Result := 15;
      Exit;
    end;
    Result := 255;
  end;

  function D_log2(num: Integer): Integer;
  var
    c: Integer;
  begin
    c := 0;
    while (num <> 0) do
    begin
      Inc(c);
      num := num shr 1;
    end;
    Result := c;
  end;

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

(*
================
D_CacheSurface
================
*)

  function D_CacheSurface(surface: msurface_p; miplevel: Integer): surfcache_p;
  var
    cache: surfcache_p;
  begin
//
// if the surface is animating or flashing, flush the cache
//
    r_drawsurf.image := R_TextureAnimation(surface^.texinfo);
    r_drawsurf.lightadj[0] := Trunc(lightstyle_p(Integer(r_newrefdef.lightstyles) + (surface^.styles[0] * SizeOf(lightstyle_t)))^.white * 128);
    r_drawsurf.lightadj[1] := Trunc(lightstyle_p(Integer(r_newrefdef.lightstyles) + (surface^.styles[1] * SizeOf(lightstyle_t)))^.white * 128);
    r_drawsurf.lightadj[2] := Trunc(lightstyle_p(Integer(r_newrefdef.lightstyles) + (surface^.styles[2] * SizeOf(lightstyle_t)))^.white * 128);
    r_drawsurf.lightadj[3] := Trunc(lightstyle_p(Integer(r_newrefdef.lightstyles) + (surface^.styles[3] * SizeOf(lightstyle_t)))^.white * 128);

//
// see if the cache holds apropriate data
//
    cache := surface^.cachespots[miplevel];

    if ((cache <> nil) and ((cache^.dlight = 0) and (surface^.dlightframe <> r_framecount)) and
      (Integer(cache^.image) = Integer(r_drawsurf.image)) and
      (cache^.lightadj[0] = r_drawsurf.lightadj[0]) and
      (cache^.lightadj[1] = r_drawsurf.lightadj[1]) and
      (cache^.lightadj[2] = r_drawsurf.lightadj[2]) and
      (cache^.lightadj[3] = r_drawsurf.lightadj[3])) then
    begin
      Result := cache;
      Exit;
    end;

//
// determine shape of surface
//
    surfscale := 1.0 / (1 shl miplevel);
    r_drawsurf.surfmip := miplevel;
    r_drawsurf.surfwidth := surface^.extents[0] shr miplevel;
    r_drawsurf.rowbytes := r_drawsurf.surfwidth;
    r_drawsurf.surfheight := surface^.extents[1] shr miplevel;

//
// allocate memory if needed
//
    if (cache = nil) then // if a texture just animated, don't reallocate it
    begin
      cache := D_SCAlloc(r_drawsurf.surfwidth, r_drawsurf.surfwidth * r_drawsurf.surfheight);
      surface^.cachespots[miplevel] := cache;
      cache^.owner := @surface^.cachespots[miplevel];
      cache^.mipscale := surfscale;
    end;

    if (surface^.dlightframe = r_framecount) then
      cache^.dlight := 1
    else
      cache^.dlight := 0;

    r_drawsurf.surfdat := @cache^.data;

    cache^.image := r_drawsurf.image;
    cache^.lightadj[0] := r_drawsurf.lightadj[0];
    cache^.lightadj[1] := r_drawsurf.lightadj[1];
    cache^.lightadj[2] := r_drawsurf.lightadj[2];
    cache^.lightadj[3] := r_drawsurf.lightadj[3];

//
// draw and light the surface texture
//
    r_drawsurf.surf := surface;

    Inc(c_surf);

 // calculate the lightings
    R_BuildLightMap;

 // rasterize the surface into the cache
    R_DrawSurface;

    Result := cache;
  end;

  procedure R_SurfacePatch;
  begin
  end;

end.

⌨️ 快捷键说明

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