git-svn-id: http://bladebattles.com/kurok/SVN@11 20cd92bb-ff49-0410-b73e-96a06e42c3b9
[kurok.git] / psp / video_hardware_entity_fragment.cpp
blob22640755461caf94f1f730b195802d08689d4372
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3 Copyright (C) 2007 Peter Mackay and Chris Swindle.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 // r_efrag.c
23 extern "C"
25 #include "../quakedef.h"
28 mnode_t *r_pefragtopnode;
31 //===========================================================================
34 ===============================================================================
36 ENTITY FRAGMENT FUNCTIONS
38 ===============================================================================
41 efrag_t **lastlink;
43 vec3_t r_emins, r_emaxs;
45 entity_t *r_addent;
49 ================
50 R_RemoveEfrags
52 Call when removing an object from the world or moving it to another position
53 ================
55 void R_RemoveEfrags (entity_t *ent)
57 efrag_t *ef, *old, *walk, **prev;
59 ef = ent->efrag;
61 while (ef)
63 prev = &ef->leaf->efrags;
64 while (1)
66 walk = *prev;
67 if (!walk)
68 break;
69 if (walk == ef)
70 { // remove this fragment
71 *prev = ef->leafnext;
72 break;
74 else
75 prev = &walk->leafnext;
78 old = ef;
79 ef = ef->entnext;
81 // put it on the free list
82 old->entnext = cl.free_efrags;
83 cl.free_efrags = old;
86 ent->efrag = NULL;
90 ===================
91 R_SplitEntityOnNode
92 ===================
94 void R_SplitEntityOnNode (mnode_t *node)
96 efrag_t *ef;
97 mplane_t *splitplane;
98 mleaf_t *leaf;
99 int sides;
101 if (node->contents == CONTENTS_SOLID)
103 return;
106 // add an efrag if the node is a leaf
108 if ( node->contents < 0)
110 if (!r_pefragtopnode)
111 r_pefragtopnode = node;
113 leaf = (mleaf_t *)node;
115 // grab an efrag off the free list
116 ef = cl.free_efrags;
117 if (!ef)
119 Con_Printf ("Too many efrags!\n");
120 return; // no free fragments...
122 cl.free_efrags = cl.free_efrags->entnext;
124 ef->entity = r_addent;
126 // add the entity link
127 *lastlink = ef;
128 lastlink = &ef->entnext;
129 ef->entnext = NULL;
131 // set the leaf links
132 ef->leaf = leaf;
133 ef->leafnext = leaf->efrags;
134 leaf->efrags = ef;
136 return;
139 // NODE_MIXED
141 splitplane = node->plane;
142 sides = BOX_ON_PLANE_SIDE(r_emins, r_emaxs, splitplane);
144 if (sides == 3)
146 // split on this plane
147 // if this is the first splitter of this bmodel, remember it
148 if (!r_pefragtopnode)
149 r_pefragtopnode = node;
152 // recurse down the contacted sides
153 if (sides & 1)
154 R_SplitEntityOnNode (node->children[0]);
156 if (sides & 2)
157 R_SplitEntityOnNode (node->children[1]);
163 ===========
164 R_AddEfrags
165 ===========
167 void R_AddEfrags (entity_t *ent)
169 model_t *entmodel;
170 int i;
172 if (!ent->model)
173 return;
175 r_addent = ent;
177 lastlink = &ent->efrag;
178 r_pefragtopnode = NULL;
180 entmodel = ent->model;
182 for (i=0 ; i<3 ; i++)
184 r_emins[i] = ent->origin[i] + entmodel->mins[i];
185 r_emaxs[i] = ent->origin[i] + entmodel->maxs[i];
188 R_SplitEntityOnNode (cl.worldmodel->nodes);
190 ent->topnode = r_pefragtopnode;
195 ================
196 R_StoreEfrags
198 // FIXME: a lot of this goes away with edge-based
199 ================
201 void R_StoreEfrags (efrag_t **ppefrag)
203 entity_t *pent;
204 model_t *clmodel;
205 efrag_t *pefrag;
208 while ((pefrag = *ppefrag) != NULL)
210 pent = pefrag->entity;
211 clmodel = pent->model;
213 switch (clmodel->type)
215 case mod_alias:
216 case mod_brush:
217 case mod_sprite:
218 pent = pefrag->entity;
220 if ((pent->visframe != r_framecount) &&
221 (cl_numvisedicts < MAX_VISEDICTS))
223 cl_visedicts[cl_numvisedicts++] = pent;
225 // mark that we've recorded this entity for this frame
226 pent->visframe = r_framecount;
229 ppefrag = &pefrag->leafnext;
230 break;
232 default:
233 Sys_Error ("R_StoreEfrags: Bad entity type %d\n", clmodel->type);