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

📄 r_model.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 4 页
字号:
  for i := 0 to mod_numknown - 1 do
  begin
    if _mod^.name[0] = #0 then
    begin
      inc(Integer(_mod), SizeOf(model_t));
      continue;
    end;
    ri.Con_Printf(PRINT_ALL, '%d : %s', _mod.extradatasize, _mod.name);
    total := total + _mod^.extradatasize;
    inc(Integer(_mod), SizeOf(model_t));
  end; {next i};
  ri.Con_Printf(PRINT_ALL, 'Total resident: %d', total);
end {procedure};

(*
===============
Mod_Init
===============
*)

procedure Mod_Init;
begin
  FillChar(mod_novis, sizeof(mod_novis), $FF);
end;

// CAK

function PCharToInt(s: PChar): Integer;
var
  s2: string;
begin
  s2 := s;
  try
    Result := StrToInt(s2);
  except
    Result := -1;
  end {try};
end;

(*
==================
Mod_ForName

Loads in a model for the given name
==================
*)

function Mod_ForName(name: PChar; crash: qboolean): model_p;
var
  _mod: model_p;
  buf: Pointer;
  i: Integer;
begin
  if (name^ = #0) then
    ri.Sys_Error(ERR_DROP, 'Mod_ForName: NULL name');

  //
  // inline models are grabbed only from worldmodel
  //
  if name[0] = '*' then
  begin
    i := PCharToInt(PChar(@name[1]));
    if (i < 1) or (r_worldmodel = nil) or (i >= r_worldmodel^.numsubmodels) then
      ri.Sys_Error(ERR_DROP, 'bad inline model number');
    Result := @mod_inline[i];
    Exit;
  end;

  //
  // search the currently loaded models
  //
  _mod := @mod_known[0];
  for i := 0 to mod_numknown - 1 do
  begin
    if strcomp(PChar(@_mod^.name), name) = 0 then
    begin
      Result := _mod;
      Exit;
    end;
    _mod := @mod_known[i];
  end;

  //
  // find a free model slot spot
  //
  _mod := nil;
  for i := 0 to mod_numknown - 1 do
  begin
    if mod_known[i].name[0] = #0 then
    begin
      _mod := @mod_known[i];
      break; // free spot
    end;
  end;
  if (_mod = nil) then
  begin // no free spot found
    if mod_numknown = MAX_MOD_KNOWN then
      ri.Sys_Error(ERR_DROP, 'mod_numknown == MAX_MOD_KNOWN');
    inc(mod_numknown);
    _mod := @mod_known[mod_numknown - 1];
  end;
  strcopy(PChar(@_mod^.name[0]), name);

  //
  // load the file
  //
  modfilelen := ri.FS_LoadFile(PChar(@_mod^.name), @buf);
  if buf = nil then
  begin
    if crash then
      ri.Sys_Error(ERR_DROP, PChar('Mod_NumForName: ' + string(_mod.name) + ' not found'));
    FillChar(_mod^.name[0], sizeof(_mod^.name), 0);
    Result := nil;
    Exit;
  end;

  loadmodel := _mod;

  //
  // fill it in
  //

  // call the apropriate loader

  case LittleLong(PInteger(buf)^) of
    IDALIASHEADER:
      begin
        loadmodel^.extradata := Hunk_Begin($200000);
        Mod_LoadAliasModel(_mod, buf);
      end;
    IDSPRITEHEADER:
      begin
        loadmodel^.extradata := Hunk_Begin($10000);
        Mod_LoadSpriteModel(_mod, buf);
      end;
    IDBSPHEADER:
      begin
        loadmodel^.extradata := Hunk_Begin($1000000);
        Mod_LoadBrushModel(_mod, buf);
      end;
  else
    begin
      ri.Sys_Error(ERR_DROP, PChar('Mod_NumForName: unknown fileid for ' + string(_mod^.name)));
    end;
  end;

  loadmodel^.extradatasize := Hunk_End;

  ri.FS_FreeFile(buf);

  Result := _mod;
end;

(*
===============
Mod_PointInLeaf
===============
*)

function Mod_PointInLeaf(const p: vec3_t; model: model_p): mleaf_p;
var
  node: mnode_p;
  d: Single;
  plane: mplane_p;
begin
  if (model = nil) or (model^.nodes = nil) then
    ri.Sys_Error(ERR_DROP, 'Mod_PointInLeaf: bad model');

  node := model^.nodes;
  while (True) do
  begin
    if node^.contents <> -1 then
    begin
      Result := mleaf_p(node);
      exit;
    end;
    plane := node^.plane;
    d := DotProduct(p, plane^.normal) - plane^.dist;
    if d > 0.0 then
      node := node^.children[0]
    else
      node := node^.children[1];
  end;
  Result := nil; // never reached
end;

(*
===================
Mod_DecompressVis
===================
*)
var
  decompressed: array[0..(MAX_MAP_LEAFS div 8) - 1] of Byte;

function Mod_DecompressVis(_in: PByte; model: model_p): PByte;
var
  c: Integer;
  _out: PByte;
  row: Integer;
begin
  row := (model^.vis^.numclusters + 7) shr 3;
  _out := @decompressed[0];

(*
    move(in^,out^,row);
*)
  if _in = nil then
  begin // no vis info, so make all visible
    while row <> 0 do
    begin
      _out^ := $FF;
      inc(Integer(_out), 1);
      dec(row, 1);
    end;
    Result := @decompressed[0];
    exit;
  end;

  repeat
    if (_in^ <> 0) then
    begin
      _out^ := _in^;
      inc(Integer(_out), 1);
      inc(Integer(_in), 1);
    end
    else
    begin
      c := PByteArray(_in)^[1];
      inc(Integer(_in), 2);
      while (c > 0) do
      begin
        _out^ := 0;
        inc(Integer(_out), 1);
        dec(c);
      end;
    end;
  until (Integer(_out) - Integer(@decompressed[0])) >= row;
  Result := @decompressed[0];
end;

(*
==============
Mod_ClusterPVS
==============
*)

function Mod_ClusterPVS(cluster: integer; model: model_p): PByte;
begin
  if (cluster = -1) or (model^.vis = nil) then
  begin
    Result := @mod_novis[0];
    exit;
  end {if};
  Result := Mod_DecompressVis(PByte(Integer(model^.vis) + model^.vis^.bitofs[cluster][DVIS_PVS]), model);
end {function};

(*
===============================================================================

     BRUSHMODEL LOADING

===============================================================================
*)

var
  mod_base: PByte;

(*
=================
Mod_LoadLighting

Converts the 24 bit lighting down to 8 bit
by taking the brightest component
=================
*)

procedure Mod_LoadLighting(l: lump_p);
var
  i, size: Integer;
  _in: PByte;
  _out: PByte;
begin
  if l^.filelen = 0 then
  begin
    loadmodel^.lightdata := nil;
    exit;
  end;
  size := Trunc(l^.filelen / 3);
  loadmodel^.lightdata := Hunk_Alloc(size);
  _in := Pointer(Integer(mod_base) + l^.fileofs);
  _out := loadmodel^.lightdata;
  for i := 0 to size - 1 do
  begin
    if (PByteArray(_in)^[0] > PByteArray(_in)^[1]) and (PByteArray(_in)^[0] > PByteArray(_in)^[2]) then
      _out^ := PByteArray(_in)^[0]
    else
    begin
      if (PByteArray(_in)^[1] > PByteArray(_in)^[0]) and (PByteArray(_in)^[1] > PByteArray(_in)^[2]) then
        _out^ := PByteArray(_in)^[1]
      else
        _out^ := PByteArray(_in)^[2];
    end;
    inc(Integer(_in), 3);
    inc(Integer(_out));
  end;
end;

var
  r_leaftovis: array[0..MAX_MAP_LEAFS - 1] of Integer;
  r_vistoleaf: array[0..MAX_MAP_LEAFS - 1] of Integer;
  r_numvisleafs: Integer;

procedure R_NumberLeafs(node: mnode_p);
var
  leaf: mleaf_p;
  leafnum: Integer;
begin
  if node^.contents <> -1 then
  begin
    leaf := mleaf_p(node);
    leafnum := (Integer(leaf) - Integer(loadmodel^.leafs)) div SizeOf(mleaf_t);
    if (leaf^.contents and CONTENTS_SOLID) <> 0 then
      Exit;
    r_leaftovis[leafnum] := r_numvisleafs;
    r_vistoleaf[r_numvisleafs] := leafnum;
    inc(r_numvisleafs);
    exit;
  end;
  R_NumberLeafs(node^.children[0]);
  R_NumberLeafs(node^.children[1]);
end;

(*
=================
Mod_LoadVisibility
=================
*)

procedure Mod_LoadVisibility(l: lump_p);
var
  i: Integer;
begin
  if (l^.filelen = 0) then
  begin
    loadmodel^.vis := nil;
    Exit;
  end;
  loadmodel^.vis := Hunk_Alloc(l^.filelen);
  move(Pointer(Integer(mod_base) + l^.fileofs)^, loadmodel^.vis^, l^.filelen);

  loadmodel^.vis^.numclusters := LittleLong(loadmodel^.vis^.numclusters);
  for i := 0 to loadmodel^.vis^.numclusters - 1 do
  begin
    loadmodel^.vis^.bitofs[i][0] := LittleLong(loadmodel^.vis^.bitofs[i][0]);
    loadmodel^.vis^.bitofs[i][1] := LittleLong(loadmodel^.vis^.bitofs[i][1]);
  end;
end;

(*
=================
Mod_LoadVertexes
=================
*)

procedure Mod_LoadVertexes(l: lump_p);
var
  _in: dvertex_p;
  _out: mvertex_p;
  i, count: Integer;
begin
  _in := Pointer(Integer(mod_base) + l^.fileofs);
  if (l^.filelen mod SizeOf(_in^)) <> 0 then
    ri.Sys_Error(ERR_DROP, PChar('MOD_LoadBmodel: funny lump size in ' + string(loadmodel^.name)));
  count := Trunc(l^.filelen / SizeOf(_in^));
  _out := Hunk_Alloc((count + 8) * sizeof(_out^)); // extra for skybox

  loadmodel^.vertexes := _out;
  loadmodel^.numvertexes := count;

  for i := 0 to count - 1 do
  begin
    _out^.position[0] := LittleFloat(_in^.point[0]);
    _out^.position[1] := LittleFloat(_in^.point[1]);
    _out^.position[2] := LittleFloat(_in^.point[2]);
    inc(Integer(_in), SizeOf(_in^));
    inc(Integer(_out), SizeOf(_out^));
  end;
end;

(*
=================
Mod_LoadSubmodels
=================
*)

procedure Mod_LoadSubmodels(l: lump_p);
var
  _in, _out: dmodel_p;
  i, j, count: Integer;
begin
  _in := Pointer(Integer(mod_base) + l^.fileofs);
  if (l^.filelen mod SizeOf(_in^)) <> 0 then
    ri.Sys_Error(ERR_DROP, PChar('MOD_LoadBmodel: funny lump size in ' + string(loadmodel^.name)));
  count := Trunc(l^.filelen / SizeOf(_in^));
  _out := Hunk_Alloc(count * sizeof(_out^));

  loadmodel^.submodels := _out;
  loadmodel^.numsubmodels := count;

  for i := 0 to count - 1 do
  begin
    for j := 0 to 2 do
    begin // spread the mins / maxs by a pixel
      _out^.mins[j] := LittleFloat(_in^.mins[j]) - 1;
      _out^.maxs[j] := LittleFloat(_in^.maxs[j]) + 1;
      _out^.origin[j] := LittleFloat(_in^.origin[j]);
    end;
    _out^.headnode := LittleLong(_in^.headnode);
    _out^.firstface := LittleLong(_in^.firstface);
    _out^.numfaces := LittleLong(_in^.numfaces);

    inc(Integer(_in), SizeOf(_in^));
    inc(Integer(_out), SizeOf(_out^));
  end;
end;

(*
=================
Mod_LoadEdges
=================
*)

procedure Mod_LoadEdges(l: lump_p);
var
  _in: dedge_p;
  _out: medge_p;
  i: Integer;
  count: Integer;
begin

⌨️ 快捷键说明

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