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

📄 r_model.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 4 页
字号:
procedure Mod_LoadPlanes(l: lump_p);
var
  i, j: Integer;
  _out: mplane_p;
  _in: dplane_p;
  count: Integer;
  bits: 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 + 6) * sizeof(_out^)); // extra for skybox

  loadmodel^.planes := _out;
  loadmodel^.numplanes := count;

  for i := 0 to count - 1 do
  begin
    bits := 0;
    for j := 0 to 2 do
    begin
      _out^.normal[j] := LittleFloat(_in^.normal[j]);
      if _out^.normal[j] < 0 then
        bits := bits or (1 shl j);
    end {next j};

    _out^.dist := LittleFloat(_in^.dist);
    _out^._type := LittleLong(_in^._type);
    _out^.signbits := bits;
    inc(Integer(_in), SizeOf(_in^));
    inc(Integer(_out), SizeOf(_out^));
  end;
end;

(*
=================
Mod_LoadBrushModel
=================
*)

procedure Mod_LoadBrushModel(_mod: model_p; buffer: Pointer);
var
  i: Integer;
  header: dheader_p;
  bm: dmodel_p;
  starmod: model_p;
begin
  loadmodel^._type := mod_brush;
  if loadmodel <> @mod_known[0] then
    ri.Sys_Error(ERR_DROP, 'Loaded a brush model after the world');

  header := dheader_p(buffer);

  i := LittleLong(header^.version);
  if i <> BSPVERSION then
    ri.Sys_Error(ERR_DROP, PChar('Mod_LoadBrushModel: ' + string(_mod^.name) + ' has wrong version number (' + IntToStr(i) + ' should be ' + IntToStr(BSPVERSION) + ')'));

// swap all the lumps
  mod_base := PByte(header);

  for i := 0 to (sizeof(dheader_t) div 4) - 1 do
    PIntegerArray(header)^[i] := LittleLong(PIntegerArray(header)^[i]);

// load into heap

  Mod_LoadVertexes(@header^.lumps[LUMP_VERTEXES]);
  Mod_LoadEdges(@header^.lumps[LUMP_EDGES]);
  Mod_LoadSurfedges(@header^.lumps[LUMP_SURFEDGES]);
  Mod_LoadLighting(@header^.lumps[LUMP_LIGHTING]);
  Mod_LoadPlanes(@header^.lumps[LUMP_PLANES]);
  Mod_LoadTexinfo(@header^.lumps[LUMP_TEXINFO]);
  Mod_LoadFaces(@header^.lumps[LUMP_FACES]);
  Mod_LoadMarksurfaces(@header^.lumps[LUMP_LEAFFACES]);
  Mod_LoadVisibility(@header^.lumps[LUMP_VISIBILITY]);
  Mod_LoadLeafs(@header^.lumps[LUMP_LEAFS]);
  Mod_LoadNodes(@header^.lumps[LUMP_NODES]);
  Mod_LoadSubmodels(@header^.lumps[LUMP_MODELS]);
  r_numvisleafs := 0;
  R_NumberLeafs(loadmodel^.nodes);

//
// set up the submodels
//
  for i := 0 to _mod^.numsubmodels - 1 do
  begin
    bm := dmodel_p(Integer(_mod^.submodels) + (i * SizeOf(dmodel_t)));
    starmod := @mod_inline[i];
    starmod^ := loadmodel^;

    starmod^.firstmodelsurface := bm^.firstface;
    starmod^.nummodelsurfaces := bm^.numfaces;
    starmod^.firstnode := bm^.headnode;
    if starmod^.firstnode >= loadmodel^.numnodes then
      ri.Sys_Error(ERR_DROP, PChar('Inline model ' + IntToStr(i) + ' has bad firstnode'));

    VectorCopy(bm^.maxs, starmod^.maxs);
    VectorCopy(bm^.mins, starmod^.mins);

    if i = 0 then
      loadmodel^ := starmod^;
  end {next i};

  R_InitSkyBox;
end;

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

ALIAS MODELS

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

(*
=================
Mod_LoadAliasModel
=================
*)

procedure Mod_LoadAliasModel(_mod: model_p; buffer: Pointer);
var
  i, j: Integer;
  pinmodel, pheader: dmdl_p;
  pinst, poutst: dstvert_p;
  pintri, pouttri: dtriangle_p;
  pinframe, poutframe: daliasframe_p;
  pincmd, poutcmd: PInteger;
  version: Integer;
begin
  pinmodel := dmdl_p(buffer);

  version := LittleLong(pinmodel^.version);
  if version <> ALIAS_VERSION then
    ri.Sys_Error(ERR_DROP, PChar(string(_mod^.name) + ' has wrong version number (' + IntToStr(version) + ' should be ' + IntToStr(ALIAS_VERSION)));

  pheader := Hunk_Alloc(LittleLong(pinmodel^.ofs_end));

  // byte swap the header fields and sanity check
  for i := 0 to (sizeof(dmdl_t) div 4) - 1 do
    PIntegerArray(pheader)^[i] := LittleLong(PIntegerArray(buffer)^[i]);

  if pheader^.skinheight > MAX_LBM_HEIGHT then
    ri.Sys_Error(ERR_DROP, PChar('model ' + string(_mod^.name) + ' has a skin taller than ' + IntToStr(MAX_LBM_HEIGHT)));

  if pheader^.num_xyz <= 0 then
    ri.Sys_Error(ERR_DROP, PChar('model ' + string(_mod^.name) + ' has no vertices'));

  if pheader^.num_xyz > MAX_VERTS then
    ri.Sys_Error(ERR_DROP, PChar('model ' + string(_mod^.name) + ' has too many vertices'));

  if pheader^.num_st <= 0 then
    ri.Sys_Error(ERR_DROP, PChar('model ' + string(_mod^.name) + ' has no st vertices'));

  if pheader^.num_tris <= 0 then
    ri.Sys_Error(ERR_DROP, PChar('model ' + string(_mod^.name) + ' has no triangles'));

  if pheader.num_frames <= 0 then
    ri.Sys_Error(ERR_DROP, PChar('model ' + string(_mod^.name) + ' has no frames'));

//
// load base s and t vertices (not used in gl version)
//
  pinst := dstvert_p(Integer(pinmodel) + pheader^.ofs_st);
  poutst := dstvert_p(Integer(pheader) + pheader^.ofs_st);

  for i := 0 to pheader^.num_st - 1 do
  begin
    poutst^.s := LittleShort(pinst^.s);
    poutst^.t := LittleShort(pinst^.t);
    Inc(Integer(pinst), SizeOf(dstvert_t));
    Inc(Integer(poutst), SizeOf(dstvert_t));
//    dstvert_a(poutst)[i].s := LittleShort(dstvert_a(pinst)[i].s);
//    dstvert_a(poutst)[i].t := LittleShort(dstvert_a(pinst)[i].t);
  end {next i};

//
// load triangle lists
//
  pintri := dtriangle_p(Integer(pinmodel) + pheader^.ofs_tris);
  pouttri := dtriangle_p(Integer(pheader) + pheader^.ofs_tris);

  for i := 0 to pheader^.num_tris - 1 do
  begin
    for j := 0 to 2 do
    begin
      pouttri^.index_xyz[j] := LittleShort(pintri^.index_xyz[j]);
      pouttri^.index_st[j] := LittleShort(pintri^.index_st[j]);
//      dtriangle_a(pouttri)[i].index_xyz[j] := LittleShort(dtriangle_a(pintri)[i].index_xyz[j]);
//      dtriangle_a(pouttri)[i].index_st[j] := LittleShort(dtriangle_a(pintri)[i].index_st[j]);
    end {next j};
    Inc(Integer(pouttri), SizeOf(pouttri^));
    Inc(Integer(pintri), SizeOf(pintri^));
  end {next i};

//
// load the frames
//
  for i := 0 to pheader^.num_frames - 1 do
  begin
    pinframe := daliasframe_p(Integer(pinmodel) + pheader^.ofs_frames + i * pheader^.framesize);
    poutframe := daliasframe_p(Integer(pheader) + pheader^.ofs_frames + i * pheader^.framesize);

    Move(pinframe^.name, poutframe^.name, SizeOf(poutframe^.name));
    for j := 0 to 2 do
    begin
      poutframe^.scale[j] := LittleFloat(pinframe^.scale[j]);
      poutframe^.translate[j] := LittleFloat(pinframe^.translate[j]);
    end {next j};
    // verts are all 8 bit, so no swapping needed
    move(pinframe^.verts[0], poutframe^.verts[0], pheader^.num_xyz * sizeof(dtrivertx_t));
  end {next i};

  _mod^._type := mod_alias;

  //
  // load the glcmds
  //
  pincmd := PInteger(Integer(pinmodel) + pheader^.ofs_glcmds);
  poutcmd := PInteger(Integer(pheader) + pheader^.ofs_glcmds);
  for i := 0 to pheader^.num_glcmds - 1 do
    PIntegerArray(poutcmd)^[i] := LittleLong(PIntegerArray(pincmd)^[i]);

  // register all skins
  move(PChar(Integer(pinmodel) + pheader^.ofs_skins)^,
    PChar(Integer(pheader) + pheader^.ofs_skins)^,
    pheader^.num_skins * MAX_SKINNAME);
  for i := 0 to pheader.num_skins - 1 do
  begin
    _mod^.skins[i] := R_FindImage(PChar(Integer(pheader) + pheader.ofs_skins + i * MAX_SKINNAME), it_skin);
  end {next i};
end {procedure};

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

SPRITE MODELS

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

(*
=================
Mod_LoadSpriteModel
=================
*)

procedure Mod_LoadSpriteModel(_mod: model_p; buffer: Pointer);
var
  sprin: dsprite_p;
  sprout: dsprite_p;
  i: Integer;
begin
  sprin := dsprite_p(buffer);
  sprout := Hunk_Alloc(modfilelen);

  sprout^.ident := LittleLong(sprin^.ident);
  sprout^.version := LittleLong(sprin^.version);
  sprout^.numframes := LittleLong(sprin^.numframes);

  if sprout^.version <> SPRITE_VERSION then
    ri.Sys_Error(ERR_DROP, PChar(string(_mod^.name) + ' has wrong version number (' + IntToStr(sprout^.version) + ' should be ' + IntToStr(SPRITE_VERSION) + ')'));

  if sprout^.numframes > MAX_MD2SKINS then
    ri.Sys_Error(ERR_DROP, PChar(string(_mod^.name) + ' has too many frames (' + IntToStr(sprout^.numframes) + ' > ' + IntToStr(MAX_MD2SKINS) + ')'));

  // byte swap everything
  for i := 0 to sprout^.numframes - 1 do
  begin
    sprout^.frames[i].width := LittleLong(sprin^.frames[i].width);
    sprout^.frames[i].height := LittleLong(sprin^.frames[i].height);
    sprout^.frames[i].origin_x := LittleLong(sprin^.frames[i].origin_x);
    sprout^.frames[i].origin_y := LittleLong(sprin^.frames[i].origin_y);
    move(sprin^.frames[i].name[0], sprout^.frames[i].name[0], MAX_SKINNAME);
    _mod^.skins[i] := R_FindImage(sprout^.frames[i].name, it_sprite);
  end;
  _mod^._type := mod_sprite;
end {procedure};

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

(*
@@@@@@@@@@@@@@@@@@@@@
R_BeginRegistration

Specifies the model that will be used as the world
@@@@@@@@@@@@@@@@@@@@@
*)

procedure R_BeginRegistration(model: PChar); cdecl;
var
  fullname: array[0..MAX_QPATH - 1] of Char;
  flushmap: cvar_p;
begin
  inc(registration_sequence);
  r_oldviewcluster := -1; // force markleafs
  Com_sprintf(fullname, sizeof(fullname), 'maps/%s.bsp', [model]);

  D_FlushCaches;
  // explicitly free the old map if different
  // this guarantees that mod_known[0] is the world map
  flushmap := ri.Cvar_Get('flushmap', '0', 0);
  if (strcomp(PChar(@mod_known[0].name), fullname) <> 0) or (flushmap^.value <> 0.0) then
    Mod_Free(@mod_known[0]);
  r_worldmodel := R_RegisterModel(fullname);
  R_NewMap;
end {procedure};

(*
@@@@@@@@@@@@@@@@@@@@@
R_RegisterModel

@@@@@@@@@@@@@@@@@@@@@
*)

function R_RegisterModel(name: PChar): Pointer;
var
  _mod: model_p;
  i: Integer;
  sprout: dsprite_p;
  pheader: dmdl_p;
begin
  _mod := Mod_ForName(name, false);
  if _mod <> nil then
  begin
    _mod^.registration_sequence := registration_sequence;

    // register any images used by the models
    if _mod^._type = mod_sprite then
    begin
      sprout := dsprite_p(_mod^.extradata);
      for i := 0 to sprout^.numframes - 1 do
        _mod^.skins[i] := R_FindImage(PChar(@sprout^.frames[i].name), it_sprite);
    end
    else
      if _mod^._type = mod_alias then
      begin
        pheader := dmdl_p(_mod^.extradata);
        for i := 0 to pheader^.num_skins - 1 do
          _mod^.skins[i] := R_FindImage(PChar(Integer(pheader) + pheader^.ofs_skins + i * MAX_SKINNAME), it_skin);
//PGM
        _mod^.numframes := pheader^.num_frames;
//PGM
      end
      else
        if _mod^._type = mod_brush then
        begin
          for i := 0 to _mod^.numtexinfo - 1 do
            mtexinfo_p(Integer(_mod^.texinfo) + (i * SizeOf(mtexinfo_t)))^.image^.registration_sequence := registration_sequence;
        end;
  end;
  Result := _mod;
end;

(*
@@@@@@@@@@@@@@@@@@@@@
R_EndRegistration

@@@@@@@@@@@@@@@@@@@@@
*)

procedure R_EndRegistration;
var
  i: Integer;
  _mod: model_p;
begin
  _mod := @mod_known[0];
  for i := 0 to mod_numknown - 1 do
  begin
    if _mod^.name[0] = #0 then
    begin
      Inc(Integer(_mod), SizeOf(_mod^));
      continue;
    end;
    if _mod^.registration_sequence <> registration_sequence then
    begin
      // don't need this model
      Hunk_Free(_mod^.extradata);
      FillChar(_mod^, sizeof(_mod^), 0);
    end
    else
    begin
      // make sure it is paged in
      Com_PageInMemory(_mod^.extradata, _mod^.extradatasize);
    end;
    Inc(Integer(_mod), SizeOf(_mod^));
  end;

  R_FreeUnusedImages;
end;

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

(*
================
Mod_Free
================
*)

procedure Mod_Free(_mod: model_p);
begin
  Hunk_Free(_mod^.extradata);
  FillChar(_mod^, sizeof(_mod^), 0);
end {procedure};

(*
================
Mod_FreeAll
================
*)

procedure Mod_FreeAll;
var
  i: Integer;
begin
  for i := 0 to mod_numknown - 1 do
  begin
    if mod_known[i].extradatasize <> 0 then
    begin
      Mod_Free(@mod_known[i]);
    end {if};
  end {next i};
end {procedure};

initialization
// Check the size of types defined in r_model.h
  Assert(sizeof(mvertex_t) = 12);
  Assert(sizeof(mplane_t) = 20);
  Assert(sizeof(medge_t) = 8);
  Assert(sizeof(mtexinfo_t) = 52);
  Assert(sizeof(msurface_t) = 68);
  Assert(sizeof(mnode_t) = 40);
  Assert(sizeof(mleaf_t) = 44);
  Assert(sizeof(modtype_t) = 4);
  Assert(sizeof(model_t) = 368);
end.

⌨️ 快捷键说明

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