📄 cm_load.c
字号:
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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.
You should have received a copy of the GNU General Public License
along with Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// cmodel.c -- model loading
#include "cm_local.h"
#ifdef BSPC
#include "../bspc/l_qfiles.h"
void SetPlaneSignbits (cplane_t *out) {
int bits, j;
// for fast box on planeside test
bits = 0;
for (j=0 ; j<3 ; j++) {
if (out->normal[j] < 0) {
bits |= 1<<j;
}
}
out->signbits = bits;
}
#endif //BSPC
// to allow boxes to be treated as brush models, we allocate
// some extra indexes along with those needed by the map
#define BOX_BRUSHES 1
#define BOX_SIDES 6
#define BOX_LEAFS 2
#define BOX_PLANES 12
#define LL(x) x=LittleLong(x)
clipMap_t cm;
int c_pointcontents;
int c_traces, c_brush_traces, c_patch_traces;
byte *cmod_base;
#ifndef BSPC
cvar_t *cm_noAreas;
cvar_t *cm_noCurves;
cvar_t *cm_playerCurveClip;
#endif
cmodel_t box_model;
cplane_t *box_planes;
cbrush_t *box_brush;
void CM_InitBoxHull (void);
void CM_FloodAreaConnections (void);
/*
===============================================================================
MAP LOADING
===============================================================================
*/
/*
=================
CMod_LoadShaders
=================
*/
void CMod_LoadShaders( lump_t *l ) {
dshader_t *in, *out;
int i, count;
in = (void *)(cmod_base + l->fileofs);
if (l->filelen % sizeof(*in)) {
Com_Error (ERR_DROP, "CMod_LoadShaders: funny lump size");
}
count = l->filelen / sizeof(*in);
if (count < 1) {
Com_Error (ERR_DROP, "Map with no shaders");
}
cm.shaders = Hunk_Alloc( count * sizeof( *cm.shaders ), h_high );
cm.numShaders = count;
Com_Memcpy( cm.shaders, in, count * sizeof( *cm.shaders ) );
out = cm.shaders;
for ( i=0 ; i<count ; i++, in++, out++ ) {
out->contentFlags = LittleLong( out->contentFlags );
out->surfaceFlags = LittleLong( out->surfaceFlags );
}
}
/*
=================
CMod_LoadSubmodels
=================
*/
void CMod_LoadSubmodels( lump_t *l ) {
dmodel_t *in;
cmodel_t *out;
int i, j, count;
int *indexes;
in = (void *)(cmod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Com_Error (ERR_DROP, "CMod_LoadSubmodels: funny lump size");
count = l->filelen / sizeof(*in);
if (count < 1)
Com_Error (ERR_DROP, "Map with no models");
cm.cmodels = Hunk_Alloc( count * sizeof( *cm.cmodels ), h_high );
cm.numSubModels = count;
if ( count > MAX_SUBMODELS ) {
Com_Error( ERR_DROP, "MAX_SUBMODELS exceeded" );
}
for ( i=0 ; i<count ; i++, in++, out++)
{
out = &cm.cmodels[i];
for (j=0 ; j<3 ; j++)
{ // spread the mins / maxs by a pixel
out->mins[j] = LittleFloat (in->mins[j]) - 1;
out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
}
if ( i == 0 ) {
continue; // world model doesn't need other info
}
// make a "leaf" just to hold the model's brushes and surfaces
out->leaf.numLeafBrushes = LittleLong( in->numBrushes );
indexes = Hunk_Alloc( out->leaf.numLeafBrushes * 4, h_high );
out->leaf.firstLeafBrush = indexes - cm.leafbrushes;
for ( j = 0 ; j < out->leaf.numLeafBrushes ; j++ ) {
indexes[j] = LittleLong( in->firstBrush ) + j;
}
out->leaf.numLeafSurfaces = LittleLong( in->numSurfaces );
indexes = Hunk_Alloc( out->leaf.numLeafSurfaces * 4, h_high );
out->leaf.firstLeafSurface = indexes - cm.leafsurfaces;
for ( j = 0 ; j < out->leaf.numLeafSurfaces ; j++ ) {
indexes[j] = LittleLong( in->firstSurface ) + j;
}
}
}
/*
=================
CMod_LoadNodes
=================
*/
void CMod_LoadNodes( lump_t *l ) {
dnode_t *in;
int child;
cNode_t *out;
int i, j, count;
in = (void *)(cmod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
count = l->filelen / sizeof(*in);
if (count < 1)
Com_Error (ERR_DROP, "Map has no nodes");
cm.nodes = Hunk_Alloc( count * sizeof( *cm.nodes ), h_high );
cm.numNodes = count;
out = cm.nodes;
for (i=0 ; i<count ; i++, out++, in++)
{
out->plane = cm.planes + LittleLong( in->planeNum );
for (j=0 ; j<2 ; j++)
{
child = LittleLong (in->children[j]);
out->children[j] = child;
}
}
}
/*
=================
CM_BoundBrush
=================
*/
void CM_BoundBrush( cbrush_t *b ) {
b->bounds[0][0] = -b->sides[0].plane->dist;
b->bounds[1][0] = b->sides[1].plane->dist;
b->bounds[0][1] = -b->sides[2].plane->dist;
b->bounds[1][1] = b->sides[3].plane->dist;
b->bounds[0][2] = -b->sides[4].plane->dist;
b->bounds[1][2] = b->sides[5].plane->dist;
}
/*
=================
CMod_LoadBrushes
=================
*/
void CMod_LoadBrushes( lump_t *l ) {
dbrush_t *in;
cbrush_t *out;
int i, count;
in = (void *)(cmod_base + l->fileofs);
if (l->filelen % sizeof(*in)) {
Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
}
count = l->filelen / sizeof(*in);
cm.brushes = Hunk_Alloc( ( BOX_BRUSHES + count ) * sizeof( *cm.brushes ), h_high );
cm.numBrushes = count;
out = cm.brushes;
for ( i=0 ; i<count ; i++, out++, in++ ) {
out->sides = cm.brushsides + LittleLong(in->firstSide);
out->numsides = LittleLong(in->numSides);
out->shaderNum = LittleLong( in->shaderNum );
if ( out->shaderNum < 0 || out->shaderNum >= cm.numShaders ) {
Com_Error( ERR_DROP, "CMod_LoadBrushes: bad shaderNum: %i", out->shaderNum );
}
out->contents = cm.shaders[out->shaderNum].contentFlags;
CM_BoundBrush( out );
}
}
/*
=================
CMod_LoadLeafs
=================
*/
void CMod_LoadLeafs (lump_t *l)
{
int i;
cLeaf_t *out;
dleaf_t *in;
int count;
in = (void *)(cmod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
count = l->filelen / sizeof(*in);
if (count < 1)
Com_Error (ERR_DROP, "Map with no leafs");
cm.leafs = Hunk_Alloc( ( BOX_LEAFS + count ) * sizeof( *cm.leafs ), h_high );
cm.numLeafs = count;
out = cm.leafs;
for ( i=0 ; i<count ; i++, in++, out++)
{
out->cluster = LittleLong (in->cluster);
out->area = LittleLong (in->area);
out->firstLeafBrush = LittleLong (in->firstLeafBrush);
out->numLeafBrushes = LittleLong (in->numLeafBrushes);
out->firstLeafSurface = LittleLong (in->firstLeafSurface);
out->numLeafSurfaces = LittleLong (in->numLeafSurfaces);
if (out->cluster >= cm.numClusters)
cm.numClusters = out->cluster + 1;
if (out->area >= cm.numAreas)
cm.numAreas = out->area + 1;
}
cm.areas = Hunk_Alloc( cm.numAreas * sizeof( *cm.areas ), h_high );
cm.areaPortals = Hunk_Alloc( cm.numAreas * cm.numAreas * sizeof( *cm.areaPortals ), h_high );
}
/*
=================
CMod_LoadPlanes
=================
*/
void CMod_LoadPlanes (lump_t *l)
{
int i, j;
cplane_t *out;
dplane_t *in;
int count;
int bits;
in = (void *)(cmod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
count = l->filelen / sizeof(*in);
if (count < 1)
Com_Error (ERR_DROP, "Map with no planes");
cm.planes = Hunk_Alloc( ( BOX_PLANES + count ) * sizeof( *cm.planes ), h_high );
cm.numPlanes = count;
out = cm.planes;
for ( i=0 ; i<count ; i++, in++, out++)
{
bits = 0;
for (j=0 ; j<3 ; j++)
{
out->normal[j] = LittleFloat (in->normal[j]);
if (out->normal[j] < 0)
bits |= 1<<j;
}
out->dist = LittleFloat (in->dist);
out->type = PlaneTypeForNormal( out->normal );
out->signbits = bits;
}
}
/*
=================
CMod_LoadLeafBrushes
=================
*/
void CMod_LoadLeafBrushes (lump_t *l)
{
int i;
int *out;
int *in;
int count;
in = (void *)(cmod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
count = l->filelen / sizeof(*in);
cm.leafbrushes = Hunk_Alloc( (count + BOX_BRUSHES) * sizeof( *cm.leafbrushes ), h_high );
cm.numLeafBrushes = count;
out = cm.leafbrushes;
for ( i=0 ; i<count ; i++, in++, out++) {
*out = LittleLong (*in);
}
}
/*
=================
CMod_LoadLeafSurfaces
=================
*/
void CMod_LoadLeafSurfaces( lump_t *l )
{
int i;
int *out;
int *in;
int count;
in = (void *)(cmod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
count = l->filelen / sizeof(*in);
cm.leafsurfaces = Hunk_Alloc( count * sizeof( *cm.leafsurfaces ), h_high );
cm.numLeafSurfaces = count;
out = cm.leafsurfaces;
for ( i=0 ; i<count ; i++, in++, out++) {
*out = LittleLong (*in);
}
}
/*
=================
CMod_LoadBrushSides
=================
*/
void CMod_LoadBrushSides (lump_t *l)
{
int i;
cbrushside_t *out;
dbrushside_t *in;
int count;
int num;
in = (void *)(cmod_base + l->fileofs);
if ( l->filelen % sizeof(*in) ) {
Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
}
count = l->filelen / sizeof(*in);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -