📄 r_model.pas
字号:
//100%
{$ALIGN 8}{$MINENUMSIZE 4}
{----------------------------------------------------------------------------}
{ }
{ File(s): r_model.c and r_model.h }
{ Content: model loading and caching }
{ }
{ Initial conversion by : Carl A Kenner (carl_kenner@hotmail.com) }
{ Initial conversion on : 23-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 : 25-Feb-2002 }
{ Updated by : Carl A Kenner (carl_kenner@hotmail.com) }
{ }
{ Updated on : 19-July-2002 }
{ Updated by : CodeFusion (Michael@Skovslund.dk) }
{ }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on: }
{ none!!! }
{----------------------------------------------------------------------------}
{ * TODO: }
{ none!!! }
{----------------------------------------------------------------------------}
unit r_model;
interface
uses
Qfiles,
Windows,
q_shared;
(*
==============================================================================
BRUSH MODELS
==============================================================================
*)
//
// in memory representation
//
// !!! if this is changed, it must be changed in asm_draw.h too !!!
type
mvertex_p = ^mvertex_t;
mvertex_t = record
position: vec3_t;
end;
mvertex_arr = array[0..MaxInt div SizeOf(mvertex_t) - 1] of mvertex_t;
mvertex_arrp = ^mvertex_arr;
const
SIDE_FRONT = 0;
SIDE_BACK = 1;
SIDE_ON = 2;
// plane_t structure
// !!! if this is changed, it must be changed in asm_i386.h too !!!
type
mplane_p = ^mplane_t;
mplane_t = record
normal: vec3_t;
dist: Single;
_type: Byte; // for texture axis selection and fast side tests
signbits: Byte; // signx + signy<<1 + signz<<1
pad: array[0..1] of Byte;
end;
mplane_arr = array[0..MaxInt div SizeOf(mplane_t) - 1] of mplane_t;
mplane_arrp = ^mplane_arr;
// FIXME: differentiate from texinfo SURF_ flags
const
SURF_PLANEBACK = 2;
SURF_DRAWSKY = 4; // sky brush face
SURF_DRAWTURB = $10;
SURF_DRAWBACKGROUND = $40;
SURF_DRAWSKYBOX = $80; // sky box
SURF_FLOW = $100; //PGM
// !!! if this is changed, it must be changed in asm_draw.h too !!!
type
medge_p = ^medge_t;
medge_t = record
v: array[0..1] of Word;
cachededgeoffset: Integer;
end;
medge_arr = array[0..MaxInt div SizeOf(medge_t) - 1] of medge_t;
medge_arrp = ^medge_arr;
/////////// CAK - TAKEN FROM r_local.h
(*
skins will be outline flood filled and mip mapped
pics and sprites with alpha will be outline flood filled
pic won't be mip mapped
model skin
sprite frame
wall texture
pic
*)
type
imagetype_p = ^imagetype_t;
imagetype_t = (
it_skin,
it_sprite,
it_wall,
it_pic,
it_sky
);
image_p = ^image_t;
image_t = record
name: array[0..MAX_QPATH - 1] of char; // game path, including extension
_type: imagetype_t;
width, height: integer;
transparent: qboolean; // true if any 255 pixels in image
registration_sequence: integer; // 0 = free
pixels: array[0..3] of pByte; // mip levels
end;
mtexinfo_p = ^mtexinfo_t;
mtexinfo_t = record
vecs: array[0..1, 0..3] of Single; // CAK - STRANGE! had to typecast this to vec3_t
mipadjust: Single;
image: image_p;
flags: integer;
numframes: integer;
next: mtexinfo_p; // animation chain
end;
mtexinfo_arr = array[0..MaxInt div SizeOf(mtexinfo_t) - 1] of mtexinfo_t;
mtexinfo_arrp = ^mtexinfo_arr;
surfcache_p = ^surfcache_t;
surfcache_t = record
next: surfcache_p;
owner: ^surfcache_p; // NULL is an empty chunk of memory
lightadj: array[0..MAXLIGHTMAPS - 1] of integer; // checked for strobe flush
dlight: integer;
size: integer; // including header
width: Cardinal;
height: Cardinal; // DEBUG only needed for debug
mipscale: single;
image: image_p;
data: array[0..3] of byte; // width*height elements
end;
msurface_p = ^msurface_t;
msurface_t = record
visframe: integer; // should be drawn when node is crossed
dlightframe: integer;
dlightbits: integer;
plane: mplane_p;
flags: integer;
firstedge: integer; // look up in model->surfedges[], negative numbers
numedges: integer; // are backwards edges
// surface generation data
cachespots: array[0..MIPLEVELS - 1] of surfcache_p;
texturemins: array[0..1] of smallint;
extents: array[0..1] of smallint;
texinfo: mtexinfo_p;
// lighting info
styles: array[0..MAXLIGHTMAPS - 1] of byte;
samples: PByte; // [numstyles*surfsize]
nextalphasurface: msurface_p;
end;
msurface_s = msurface_t;
msurface_pp = ^msurface_p;
msurface_arr = array[0..MaxInt div SizeOf(msurface_t) - 1] of msurface_t;
msurface_arrp = ^msurface_arr;
mnode_p = ^mnode_t;
mnode_t = record
// common with leaf
contents: integer; // CONTENTS_NODE, to differentiate from leafs
visframe: integer; // node needs to be traversed if current
minmaxs: array[0..5] of smallint; // for bounding box culling
parent: mnode_p;
// node specific
plane: mplane_p;
children: array[0..1] of mnode_p;
firstsurface: word;
numsurfaces: word;
end;
mnode_s = mnode_t;
mnode_arr = array[0..MaxInt div SizeOf(mnode_t) - 1] of mnode_t;
mnode_arrp = ^mnode_arr;
mleaf_p = ^mleaf_t;
mleaf_t = record
// common with node
contents: integer; // wil be something other than CONTENTS_NODE
visframe: integer; // node needs to be traversed if current
minmaxs: array[0..5] of smallint; // for bounding box culling
parent: mnode_p;
// leaf specific
cluster: integer;
area: integer;
firstmarksurface: msurface_pp; // CAK - pointer to pointer to msurface_t
nummarksurfaces: integer;
key: integer; // BSP sequence number for leaf's contents
end;
mleaf_arr = array[0..MaxInt div SizeOf(mleaf_t) - 1] of mleaf_t;
mleaf_arrp = ^mleaf_arr;
//===================================================================
//
// Whole model
//
modtype_p = ^modtype_t;
modtype_t = (mod_bad,
mod_brush,
mod_sprite,
mod_alias);
model_p = ^model_t;
model_t = record
name: array[0..MAX_QPATH - 1] of Char;
registration_sequence: integer;
_type: modtype_t;
numframes: integer;
flags: integer;
// volume occupied by the model graphics
mins: vec3_t;
maxs: vec3_t;
// solid volume for clipping (sent from server)
clipbox: qboolean;
clipmins: vec3_t;
clipmaxs: vec3_t;
// brush model
firstmodelsurface: integer;
nummodelsurfaces: integer;
numsubmodels: integer;
submodels: dmodel_p;
numplanes: integer;
planes: mplane_p;
numleafs: integer; // number of visible leafs, not counting 0
leafs: mleaf_p;
numvertexes: integer;
vertexes: mvertex_p;
numedges: integer;
edges: medge_p;
numnodes: integer;
firstnode: integer;
nodes: mnode_p;
numtexinfo: integer;
texinfo: mtexinfo_p;
numsurfaces: integer;
surfaces: msurface_p;
numsurfedges: integer;
surfedges: PInteger;
nummarksurfaces: integer;
marksurfaces: msurface_pp;
vis: dvis_p;
lightdata: PByte;
// for alias models and sprites
skins: array[0..MAX_MD2SKINS - 1] of image_p;
extradata: pointer;
extradatasize: integer;
end;
//============================================================================
const
CONTENTS_NODE = -1;
procedure Mod_Init;
(*
void Mod_ClearAll (void);
*)
function Mod_ForName(name: PChar; crash: qboolean): model_p;
(*
void *Mod_Extradata (model_t *mod); // handles caching
void Mod_TouchModel (char *name);
*)
function Mod_PointInLeaf(const p: vec3_t; model: model_p): mleaf_p;
function Mod_ClusterPVS(cluster: integer; model: model_p): PByte;
procedure Mod_Modellist_f; cdecl;
procedure Mod_FreeAll;
procedure Mod_Free(_mod: model_p);
function R_RegisterModel(name: PChar): Pointer; cdecl;
procedure R_BeginRegistration(model: PChar); cdecl;
procedure R_EndRegistration; cdecl;
var
registration_sequence: Integer;
loadmodel: model_p; // used by r_rast
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
implementation
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
uses
sysutils,
q_shwin,
r_local,
r_rast,
r_image,
r_surf,
r_main;
//////////////////////////////////////////////
// CAK - Stuff that doesn't exist in Delphi 3
//////////////////////////////////////////////
//var
// loadname : array[0..31] of Char; // for hunk tags
(*
function floor(x: Single): Integer;
begin
if Trunc(x) = x then
Result := Trunc(x)
else
if x < 0 then
Result := Trunc(x) - 1
else
Result := Trunc(x);
end;
function ceil(x: Single): Integer;
begin
if Trunc(x) = x then
Result := Trunc(x)
else
if x < 0 then
Result := Trunc(x)
else
Result := Trunc(x) + 1;
end;
*)
// models.c -- model loading and caching
// models are the only shared resource between a client and server running
// on the same machine.
procedure Mod_LoadSpriteModel(_mod: model_p; buffer: Pointer); forward;
procedure Mod_LoadBrushModel(_mod: model_p; buffer: Pointer); forward;
procedure Mod_LoadAliasModel(_mod: model_p; buffer: Pointer); forward;
//CAK - BUG!!! This function prototype is for a function which
//doesn't exist ANYWHERE in the original C code!!!
//function Mod_LoadModel(_mod: model_p; crash: qboolean): model_p; forward;
const
MAX_MOD_KNOWN = 256;
var
mod_novis: array[0..(MAX_MAP_LEAFS div 8) - 1] of byte;
mod_known: array[0..MAX_MOD_KNOWN - 1] of model_t;
mod_numknown: integer;
// the inline * models from the current map are kept seperate
mod_inline: array[0..MAX_MOD_KNOWN - 1] of model_t;
modfilelen: Integer;
//===============================================================================
function IntToStr2(Value: Integer; Size: Integer): string;
begin
Result := IntToStr(Value);
while length(Result) < size do
Result := ' ' + Result;
end {function};
(*
================
Mod_Modellist_f
================
*)
procedure Mod_Modellist_f; cdecl;
var
i: Integer;
_mod: model_p;
total: Integer;
begin
total := 0;
ri.Con_Printf(PRINT_ALL, 'Loaded models:'#13#10);
_mod := @mod_known[0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -