mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
[renderer] Support multiple entity queues
While there's currently only the one still, this will allow the entities to be multiply queued for multi-pass rendering (eg, shadows). As the avoidance of putting an entity in the same queue more than once relies on the entity id, all entities now come from the scene (which is stored in cl_world in the client code for nq and qw), thus the extensive changes in the clients.
This commit is contained in:
parent
6573acbc74
commit
d69355f521
53 changed files with 741 additions and 618 deletions
|
@ -119,7 +119,6 @@ typedef struct vid_render_funcs_s {
|
|||
void (*R_RemoveEfrags) (entity_t *ent);
|
||||
void (*R_LineGraph) (int x, int y, int *h_vals, int count, int height);
|
||||
dlight_t *(*R_AllocDlight) (int key);
|
||||
entity_t *(*R_AllocEntity) (void);
|
||||
void (*R_MaxDlightsCheck) (struct cvar_s *var);
|
||||
void (*R_DecayLights) (double frametime);
|
||||
|
||||
|
|
|
@ -155,7 +155,6 @@ typedef struct visibility_s {
|
|||
struct mnode_s *topnode; // bmodels, first world node that
|
||||
// splits bmodel, or NULL if not split
|
||||
// applies to other models, too
|
||||
int visframe; // last frame this entity was
|
||||
// found in an active leaf
|
||||
int trivial_accept; // view clipping (frustum and depth)
|
||||
} visibility_t;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "QF/darray.h"
|
||||
#include "QF/qtypes.h"
|
||||
#include "QF/set.h"
|
||||
#include "QF/simd/vec4f.h"
|
||||
#include "QF/simd/mat4f.h"
|
||||
|
||||
|
@ -46,6 +47,38 @@
|
|||
|
||||
#include "QF/render.h" //FIXME move entity_t here
|
||||
|
||||
typedef struct entqueue_s {
|
||||
set_t *queued_ents;
|
||||
entityset_t *ent_queues;
|
||||
int num_queues;
|
||||
} entqueue_t;
|
||||
|
||||
#define ENTINLINE GNU89INLINE inline
|
||||
|
||||
entqueue_t *EntQueue_New (int num_queues);
|
||||
void EntQueue_Delete (entqueue_t *queue);
|
||||
ENTINLINE void EntQueue_AddEntity (entqueue_t *queue, entity_t *ent,
|
||||
int queue_num);
|
||||
void EntQueue_Clear (entqueue_t *queue);
|
||||
|
||||
#undef ENTINLINE
|
||||
#ifndef IMPLEMENT_ENTITY_Funcs
|
||||
#define ENTINLINE GNU89INLINE inline
|
||||
#else
|
||||
#define ENTINLINE VISIBLE
|
||||
#endif
|
||||
|
||||
ENTINLINE
|
||||
void
|
||||
EntQueue_AddEntity (entqueue_t *queue, entity_t *ent, int queue_num)
|
||||
{
|
||||
if (!set_is_member (queue->queued_ents, ent->id)) {
|
||||
// entity ids are negative (ones-complement)
|
||||
set_add (queue->queued_ents, -ent->id);//FIXME use ~
|
||||
DARRAY_APPEND (&queue->ent_queues[queue_num], ent);
|
||||
}
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
#endif//__QF_scene_entity_h
|
||||
|
|
|
@ -31,9 +31,16 @@
|
|||
#ifndef __client_entities_h
|
||||
#define __client_entities_h
|
||||
|
||||
#include "QF/darray.h"
|
||||
#include "QF/msg.h"
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
#include "QF/simd/types.h"
|
||||
|
||||
typedef struct entitystateset_s DARRAY_TYPE (struct entity_state_s)
|
||||
entitystateset_t;
|
||||
extern entitystateset_t cl_static_entities;
|
||||
|
||||
// entity_state_t is the information conveyed from the server
|
||||
// in an update message
|
||||
typedef struct entity_state_s {
|
||||
|
|
|
@ -96,15 +96,12 @@ typedef enum TE_qwEffect {
|
|||
//FIXME find a better way to get this info from the parser
|
||||
typedef struct TEntContext_s {
|
||||
vec4f_t simorg;
|
||||
struct model_s *worldModel;
|
||||
int playerEntity;
|
||||
} TEntContext_t;
|
||||
|
||||
struct msg_s;
|
||||
struct entity_s;
|
||||
|
||||
extern struct scene_s *cl_scene;
|
||||
|
||||
void CL_TEnts_Init (void);
|
||||
void CL_Init_Entity (struct entity_s *ent);
|
||||
void CL_ClearTEnts (void);
|
||||
|
|
70
include/client/world.h
Normal file
70
include/client/world.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
world.h
|
||||
|
||||
Client world scene management
|
||||
|
||||
Copyright (C) 2022 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2022/3/4
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __client_world_h
|
||||
#define __client_world_h
|
||||
|
||||
#include "QF/darray.h"
|
||||
#include "QF/msg.h"
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
#include "QF/simd/types.h"
|
||||
|
||||
typedef struct modelset_s DARRAY_TYPE (struct model_s *) modelset_t;
|
||||
|
||||
typedef struct worldscene_s {
|
||||
struct scene_s *scene;
|
||||
struct plitem_s *edicts;
|
||||
struct plitem_s *worldspawn;
|
||||
struct model_s *worldmodel;
|
||||
modelset_t models;
|
||||
} worldscene_t;
|
||||
|
||||
extern worldscene_t cl_world;
|
||||
|
||||
struct msg_s;
|
||||
struct entity_state_s;
|
||||
|
||||
void CL_World_Init (void);
|
||||
|
||||
// PROTOCOL_FITZQUAKE -- flags for entity baseline messages
|
||||
#define B_LARGEMODEL (1<<0) // modelindex is short instead of byte
|
||||
#define B_LARGEFRAME (1<<1) // frame is short instead of byte
|
||||
#define B_ALPHA (1<<2) // 1 byte, uses ENTALPHA_ENCODE, not sent if ENTALPHA_DEFAULT
|
||||
void CL_ParseBaseline (struct msg_s *msg, struct entity_state_s *baseline,
|
||||
int version);
|
||||
/*
|
||||
Static entities are non-interactive world objects like torches
|
||||
*/
|
||||
void CL_ParseStatic (struct msg_s *msg, int version);
|
||||
void CL_MapCfg (const char *mapname);
|
||||
void CL_World_NewMap (const char *mapname, const char *skyname);
|
||||
|
||||
#endif//__client_world_h
|
|
@ -81,10 +81,6 @@ void R_SetVrect (const vrect_t *pvrect, vrect_t *pvrectin, int lineadj);
|
|||
void R_LoadSkys (const char *);
|
||||
|
||||
void R_ClearEfrags (void);
|
||||
void R_ClearEnts (void);
|
||||
void R_EnqueueEntity (struct entity_s *ent);
|
||||
entity_t *R_AllocEntity (void);
|
||||
void R_FreeAllEntities (void);
|
||||
|
||||
void R_FindNearLights (const vec3_t pos, int count, dlight_t **lights);
|
||||
dlight_t *R_AllocDlight (int key);
|
||||
|
|
|
@ -292,7 +292,7 @@ extern mleaf_t *r_viewleaf;
|
|||
extern int r_clipflags;
|
||||
extern int r_dlightframecount;
|
||||
|
||||
extern struct entity_s *r_ent_queue[mod_num_types];
|
||||
extern struct entqueue_s *r_ent_queue;
|
||||
struct dlight_s;
|
||||
|
||||
extern vec3_t lightspot;
|
||||
|
|
|
@ -10,6 +10,7 @@ libs_client_libQFclient_la_SOURCES= \
|
|||
libs/client/cl_particles.c \
|
||||
libs/client/cl_temp_entities.c \
|
||||
libs/client/cl_view.c \
|
||||
libs/client/cl_world.c \
|
||||
libs/client/hud.c \
|
||||
libs/client/locs.c \
|
||||
libs/client/old_keys.c
|
||||
|
|
|
@ -31,11 +31,18 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "QF/render.h" //FIXME for entity_t
|
||||
#include "QF/msg.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/scene.h"
|
||||
#include "QF/simd/vec4f.h"
|
||||
|
||||
#include "QF/plugin/vid_render.h" //FIXME
|
||||
|
||||
#include "client/entities.h"
|
||||
#include "client/temp_entities.h"
|
||||
|
||||
entitystateset_t cl_static_entities = DARRAY_STATIC_INIT (32);
|
||||
|
||||
/* QW has a max of 512 entities and wants 64 frames of data per entity, plus
|
||||
the baseline data (512 * (64 + 1) = 33280), but NQ has a max of 32000
|
||||
|
|
|
@ -52,10 +52,11 @@
|
|||
#include "client/entities.h"
|
||||
#include "client/particles.h"
|
||||
#include "client/temp_entities.h"
|
||||
#include "client/world.h"
|
||||
|
||||
typedef struct tent_s {
|
||||
struct tent_s *next;
|
||||
entity_t ent;
|
||||
entity_t *ent;
|
||||
} tent_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -86,7 +87,6 @@ typedef struct tent_obj_s {
|
|||
|
||||
static PR_RESMAP (tent_t) temp_entities;
|
||||
static PR_RESMAP (tent_obj_t) tent_objects;
|
||||
scene_t *cl_scene;
|
||||
static tent_obj_t *cl_beams;
|
||||
static tent_obj_t *cl_explosions;
|
||||
|
||||
|
@ -137,8 +137,6 @@ CL_TEnts_Precache (int phase)
|
|||
void
|
||||
CL_TEnts_Init (void)
|
||||
{
|
||||
cl_scene = Scene_NewScene ();
|
||||
|
||||
QFS_GamedirCallback (CL_TEnts_Precache);
|
||||
CL_TEnts_Precache (1);
|
||||
for (int i = 0; i < 360; i++) {
|
||||
|
@ -150,12 +148,12 @@ CL_TEnts_Init (void)
|
|||
void
|
||||
CL_Init_Entity (entity_t *ent)
|
||||
{
|
||||
if (ent->transform) {
|
||||
Transform_Delete (ent->transform);
|
||||
}
|
||||
memset (ent, 0, sizeof (*ent));
|
||||
memset (&ent->animation, 0, sizeof (ent->animation));
|
||||
memset (&ent->visibility, 0, sizeof (ent->visibility));
|
||||
memset (&ent->renderer, 0, sizeof (ent->renderer));
|
||||
ent->active = 1;
|
||||
ent->old_origin = (vec4f_t) {};
|
||||
|
||||
ent->transform = Transform_New (cl_scene, 0);
|
||||
ent->renderer.skin = 0;
|
||||
QuatSet (1.0, 1.0, 1.0, 1.0, ent->renderer.colormod);
|
||||
ent->animation.pose1 = ent->animation.pose2 = -1;
|
||||
|
@ -165,9 +163,9 @@ static tent_t *
|
|||
new_temp_entity (void)
|
||||
{
|
||||
tent_t *tent = PR_RESNEW_NC (temp_entities);
|
||||
tent->ent.transform = 0;
|
||||
tent->ent = Scene_CreateEntity (cl_world.scene);
|
||||
tent->next = 0;
|
||||
CL_Init_Entity (&tent->ent);
|
||||
CL_Init_Entity (tent->ent);
|
||||
return tent;
|
||||
}
|
||||
|
||||
|
@ -177,7 +175,7 @@ free_temp_entities (tent_t *tents)
|
|||
tent_t **t = &tents;
|
||||
|
||||
while (*t) {
|
||||
Transform_Delete ((*t)->ent.transform);//FIXME reuse?
|
||||
Scene_DestroyEntity (cl_world.scene, (*t)->ent);//FIXME reuse?
|
||||
t = &(*t)->next;
|
||||
}
|
||||
*t = temp_entities._free;
|
||||
|
@ -215,8 +213,8 @@ beam_clear (beam_t *b)
|
|||
tent_t *t;
|
||||
|
||||
for (t = b->tents; t; t = t->next) {
|
||||
r_funcs->R_RemoveEfrags (&t->ent);
|
||||
t->ent.visibility.efrag = 0;
|
||||
r_funcs->R_RemoveEfrags (t->ent);
|
||||
t->ent->visibility.efrag = 0;
|
||||
}
|
||||
free_temp_entities (b->tents);
|
||||
b->tents = 0;
|
||||
|
@ -263,17 +261,17 @@ beam_setup (beam_t *b, qboolean transform, double time, TEntContext_t *ctx)
|
|||
|
||||
vec4f_t position = org + d * dist;
|
||||
d += 1.0;
|
||||
tent->ent.renderer.model = b->model;
|
||||
tent->ent->renderer.model = b->model;
|
||||
if (transform) {
|
||||
seed = seed * BEAM_SEED_PRIME;
|
||||
Transform_SetLocalTransform (tent->ent.transform, scale,
|
||||
Transform_SetLocalTransform (tent->ent->transform, scale,
|
||||
qmulf (rotation,
|
||||
beam_rolls[seed % 360]),
|
||||
position);
|
||||
} else {
|
||||
Transform_SetLocalPosition (tent->ent.transform, position);
|
||||
Transform_SetLocalPosition (tent->ent->transform, position);
|
||||
}
|
||||
r_funcs->R_AddEfrags (&ctx->worldModel->brush, &tent->ent);
|
||||
r_funcs->R_AddEfrags (&cl_world.worldmodel->brush, tent->ent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -377,8 +375,8 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx,
|
|||
if (!cl_spr_explod->cache.data) {
|
||||
cl_spr_explod = Mod_ForName ("progs/s_explod.spr", true);
|
||||
}
|
||||
ex->tent->ent.renderer.model = cl_spr_explod;
|
||||
Transform_SetLocalPosition (ex->tent->ent.transform,//FIXME
|
||||
ex->tent->ent->renderer.model = cl_spr_explod;
|
||||
Transform_SetLocalPosition (ex->tent->ent->transform,//FIXME
|
||||
(vec4f_t) {VectorExpand (position), 1});
|
||||
break;
|
||||
case TE_Explosion2:
|
||||
|
@ -601,7 +599,7 @@ CL_UpdateBeams (double time, TEntContext_t *ctx)
|
|||
// add new entities for the lightning
|
||||
for (t = b->tents; t; t = t->next) {
|
||||
seed = seed * BEAM_SEED_PRIME;
|
||||
Transform_SetLocalRotation (t->ent.transform,
|
||||
Transform_SetLocalRotation (t->ent->transform,
|
||||
qmulf (b->rotation,
|
||||
beam_rolls[seed % 360]));
|
||||
}
|
||||
|
@ -618,7 +616,7 @@ CL_UpdateExplosions (double time, TEntContext_t *ctx)
|
|||
|
||||
for (to = &cl_explosions; *to; ) {
|
||||
ex = &(*to)->to.ex;
|
||||
ent = &ex->tent->ent;
|
||||
ent = ex->tent->ent;
|
||||
f = 10 * (time - ex->start);
|
||||
if (f >= ent->renderer.model->numframes) {
|
||||
tent_obj_t *_to;
|
||||
|
@ -634,7 +632,7 @@ CL_UpdateExplosions (double time, TEntContext_t *ctx)
|
|||
|
||||
ent->animation.frame = f;
|
||||
if (!ent->visibility.efrag) {
|
||||
r_funcs->R_AddEfrags (&ctx->worldModel->brush, ent);
|
||||
r_funcs->R_AddEfrags (&cl_world.worldmodel->brush, ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -675,8 +673,8 @@ CL_ClearProjectiles (void)
|
|||
tent_t *tent;
|
||||
|
||||
for (tent = cl_projectiles; tent; tent = tent->next) {
|
||||
r_funcs->R_RemoveEfrags (&tent->ent);
|
||||
tent->ent.visibility.efrag = 0;
|
||||
r_funcs->R_RemoveEfrags (tent->ent);
|
||||
tent->ent->visibility.efrag = 0;
|
||||
}
|
||||
free_temp_entities (cl_projectiles);
|
||||
cl_projectiles = 0;
|
||||
|
@ -712,7 +710,7 @@ CL_ParseProjectiles (qmsg_t *net_message, qboolean nail2, TEntContext_t *ctx)
|
|||
*tail = tent;
|
||||
tail = &tent->next;
|
||||
|
||||
pr = &tent->ent;
|
||||
pr = tent->ent;
|
||||
pr->renderer.model = cl_spike;
|
||||
pr->renderer.skin = 0;
|
||||
position[0] = ((bits[0] + ((bits[1] & 15) << 8)) << 1) - 4096;
|
||||
|
@ -721,9 +719,9 @@ CL_ParseProjectiles (qmsg_t *net_message, qboolean nail2, TEntContext_t *ctx)
|
|||
angles[0] = (bits[4] >> 4) * (360.0 / 16.0);
|
||||
angles[1] = bits[5] * (360.0 / 256.0);
|
||||
angles[2] = 0;
|
||||
CL_TransformEntity (&tent->ent, 1, angles, position);
|
||||
CL_TransformEntity (tent->ent, 1, angles, position);
|
||||
|
||||
r_funcs->R_AddEfrags (&ctx->worldModel->brush, &tent->ent);
|
||||
r_funcs->R_AddEfrags (&cl_world.worldmodel->brush, tent->ent);
|
||||
}
|
||||
|
||||
*tail = cl_projectiles;
|
||||
|
|
|
@ -43,8 +43,8 @@
|
|||
#include "client/entities.h"
|
||||
#include "client/hud.h"
|
||||
#include "client/input.h"
|
||||
#include "client/temp_entities.h"//FIXME for cl_scene
|
||||
#include "client/view.h"
|
||||
#include "client/world.h"
|
||||
|
||||
/*
|
||||
The view is allowed to move slightly from it's true position for bobbing,
|
||||
|
@ -763,7 +763,7 @@ V_Init (viewstate_t *viewstate)
|
|||
"Used when you are underwater, hit, have the Ring of "
|
||||
"Shadows, or Quad Damage. (v_cshift r g b intensity)");
|
||||
|
||||
viewstate->camera_transform = Transform_New (cl_scene, 0);
|
||||
viewstate->camera_transform = Transform_New (cl_world.scene, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
224
libs/client/cl_world.c
Normal file
224
libs/client/cl_world.c
Normal file
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
cl_entities.c
|
||||
|
||||
Client side entity management
|
||||
|
||||
Copyright (C) 2012 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2012/6/28
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "QF/cbuf.h"
|
||||
#include "QF/cmd.h"
|
||||
#include "QF/idparse.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/plist.h"
|
||||
#include "QF/progs.h"
|
||||
#include "QF/msg.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/scene.h"
|
||||
#include "QF/simd/vec4f.h"
|
||||
|
||||
#include "QF/plugin/vid_render.h" //FIXME
|
||||
|
||||
#include "client/entities.h"
|
||||
#include "client/temp_entities.h"
|
||||
#include "client/world.h"
|
||||
|
||||
worldscene_t cl_world = {
|
||||
.models = DARRAY_STATIC_INIT (32),
|
||||
};
|
||||
|
||||
void
|
||||
CL_World_Init (void)
|
||||
{
|
||||
cl_world.scene = Scene_NewScene ();
|
||||
}
|
||||
|
||||
void
|
||||
CL_ParseBaseline (qmsg_t *msg, entity_state_t *baseline, int version)
|
||||
{
|
||||
int bits = 0;
|
||||
|
||||
if (version == 2)
|
||||
bits = MSG_ReadByte (msg);
|
||||
|
||||
if (bits & B_LARGEMODEL)
|
||||
baseline->modelindex = MSG_ReadShort (msg);
|
||||
else
|
||||
baseline->modelindex = MSG_ReadByte (msg);
|
||||
|
||||
if (bits & B_LARGEFRAME)
|
||||
baseline->frame = MSG_ReadShort (msg);
|
||||
else
|
||||
baseline->frame = MSG_ReadByte (msg);
|
||||
|
||||
baseline->colormap = MSG_ReadByte (msg);
|
||||
baseline->skinnum = MSG_ReadByte (msg);
|
||||
|
||||
MSG_ReadCoordAngleV (msg, &baseline->origin[0], baseline->angles);
|
||||
baseline->origin[3] = 1;//FIXME
|
||||
|
||||
if (bits & B_ALPHA)
|
||||
baseline->alpha = MSG_ReadByte (msg);
|
||||
else
|
||||
baseline->alpha = 255;//FIXME alpha
|
||||
baseline->scale = 16;
|
||||
baseline->glow_size = 0;
|
||||
baseline->glow_color = 254;
|
||||
baseline->colormod = 255;
|
||||
}
|
||||
|
||||
void
|
||||
CL_ParseStatic (qmsg_t *msg, int version)
|
||||
{
|
||||
entity_t *ent;
|
||||
entity_state_t es;
|
||||
|
||||
ent = Scene_CreateEntity (cl_world.scene);
|
||||
CL_Init_Entity (ent);
|
||||
|
||||
CL_ParseBaseline (msg, &es, version);
|
||||
DARRAY_APPEND (&cl_static_entities, es);
|
||||
|
||||
// copy it to the current state
|
||||
ent->renderer.model = cl_world.models.a[es.modelindex];
|
||||
ent->animation.frame = es.frame;
|
||||
ent->renderer.skinnum = es.skinnum;
|
||||
|
||||
CL_TransformEntity (ent, es.scale / 16.0, es.angles, es.origin);
|
||||
|
||||
r_funcs->R_AddEfrags (&cl_world.worldmodel->brush, ent);
|
||||
}
|
||||
|
||||
static void
|
||||
map_cfg (const char *mapname, int all)
|
||||
{
|
||||
char *name = malloc (strlen (mapname) + 4 + 1);
|
||||
cbuf_t *cbuf = Cbuf_New (&id_interp);
|
||||
QFile *f;
|
||||
|
||||
QFS_StripExtension (mapname, name);
|
||||
strcat (name, ".cfg");
|
||||
f = QFS_FOpenFile (name);
|
||||
if (f) {
|
||||
Qclose (f);
|
||||
Cmd_Exec_File (cbuf, name, 1);
|
||||
} else {
|
||||
Cmd_Exec_File (cbuf, "maps_default.cfg", 1);
|
||||
}
|
||||
if (all) {
|
||||
Cbuf_Execute_Stack (cbuf);
|
||||
} else {
|
||||
Cbuf_Execute_Sets (cbuf);
|
||||
}
|
||||
free (name);
|
||||
Cbuf_Delete (cbuf);
|
||||
}
|
||||
|
||||
void
|
||||
CL_MapCfg (const char *mapname)
|
||||
{
|
||||
map_cfg (mapname, 0);
|
||||
}
|
||||
|
||||
static plitem_t *
|
||||
map_ent (const char *mapname)
|
||||
{
|
||||
static progs_t edpr;
|
||||
char *name = malloc (strlen (mapname) + 4 + 1);
|
||||
char *buf;
|
||||
plitem_t *edicts = 0;
|
||||
QFile *ent_file;
|
||||
|
||||
QFS_StripExtension (mapname, name);
|
||||
strcat (name, ".ent");
|
||||
ent_file = QFS_VOpenFile (name, 0, cl_world.models.a[1]->vpath);
|
||||
if ((buf = (char *) QFS_LoadFile (ent_file, 0))) {
|
||||
edicts = ED_Parse (&edpr, buf);
|
||||
free (buf);
|
||||
} else {
|
||||
edicts = ED_Parse (&edpr, cl_world.models.a[1]->brush.entities);
|
||||
}
|
||||
free (name);
|
||||
return edicts;
|
||||
}
|
||||
|
||||
static void
|
||||
CL_LoadSky (const char *name)
|
||||
{
|
||||
plitem_t *worldspawn = cl_world.worldspawn;
|
||||
plitem_t *item;
|
||||
static const char *sky_keys[] = {
|
||||
"sky", // Q2/DarkPlaces
|
||||
"skyname", // old QF
|
||||
"qlsky", // QuakeLives
|
||||
0
|
||||
};
|
||||
|
||||
if (!name) {
|
||||
if (!worldspawn) {
|
||||
r_funcs->R_LoadSkys (0);
|
||||
return;
|
||||
}
|
||||
for (const char **key = sky_keys; *key; key++) {
|
||||
if ((item = PL_ObjectForKey (cl_world.worldspawn, *key))) {
|
||||
name = PL_String (item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
r_funcs->R_LoadSkys (name);
|
||||
}
|
||||
|
||||
void
|
||||
CL_World_NewMap (const char *mapname, const char *skyname)
|
||||
{
|
||||
cl_static_entities.size = 0;
|
||||
r_funcs->R_NewMap (cl_world.worldmodel,
|
||||
cl_world.models.a, cl_world.models.size);
|
||||
if (cl_world.models.a[1] && cl_world.models.a[1]->brush.entities) {
|
||||
if (cl_world.edicts) {
|
||||
PL_Free (cl_world.edicts);
|
||||
}
|
||||
cl_world.edicts = map_ent (mapname);
|
||||
if (cl_world.edicts) {
|
||||
cl_world.worldspawn = PL_ObjectAtIndex (cl_world.edicts, 0);
|
||||
CL_LoadSky (skyname);
|
||||
if (r_funcs->Fog_ParseWorldspawn)
|
||||
r_funcs->Fog_ParseWorldspawn (cl_world.worldspawn);
|
||||
}
|
||||
}
|
||||
map_cfg (mapname, 1);
|
||||
}
|
|
@ -9,6 +9,7 @@ libs_scene_libQFscene_la_LIBADD= $(scene_deps)
|
|||
libs_scene_libQFscene_la_DEPENDENCIES= $(scene_deps)
|
||||
libs_scene_libQFscene_la_SOURCES= \
|
||||
libs/scene/camera.c \
|
||||
libs/scene/entity.c \
|
||||
libs/scene/hierarchy.c \
|
||||
libs/scene/scene.c \
|
||||
libs/scene/transform.c
|
||||
|
|
71
libs/scene/entity.c
Normal file
71
libs/scene/entity.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
entity.c
|
||||
|
||||
Entity management
|
||||
|
||||
Copyright (C) 2022 Bill Currke
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "QF/set.h"
|
||||
|
||||
#define IMPLEMENT_ENTITY_Funcs
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/scene.h"
|
||||
|
||||
#include "scn_internal.h"
|
||||
|
||||
entqueue_t *
|
||||
EntQueue_New (int num_queues)
|
||||
{
|
||||
int size = sizeof (entqueue_t) + num_queues * sizeof (entityset_t);
|
||||
entqueue_t *queue = calloc (1, size);
|
||||
queue->queued_ents = set_new ();
|
||||
queue->ent_queues = (entityset_t *) (queue + 1);
|
||||
queue->num_queues = num_queues;
|
||||
for (int i = 0; i < num_queues; i++) {
|
||||
queue->ent_queues[i].grow = 64;
|
||||
}
|
||||
return queue;
|
||||
}
|
||||
|
||||
void
|
||||
EntQueue_Delete (entqueue_t *queue)
|
||||
{
|
||||
for (int i = 0; i < queue->num_queues; i++) {
|
||||
DARRAY_CLEAR (&queue->ent_queues[i]);
|
||||
}
|
||||
set_delete (queue->queued_ents);
|
||||
free (queue);
|
||||
}
|
||||
|
||||
void
|
||||
EntQueue_Clear (entqueue_t *queue)
|
||||
{
|
||||
for (int i = 0; i < queue->num_queues; i++) {
|
||||
queue->ent_queues[i].size = 0;
|
||||
}
|
||||
set_empty (queue->queued_ents);
|
||||
}
|
|
@ -551,7 +551,6 @@ gl_overbright_f (cvar_t *var)
|
|||
{
|
||||
int num;
|
||||
model_t *m;
|
||||
entity_t *ent;
|
||||
mod_brush_t *brush;
|
||||
|
||||
if (!var)
|
||||
|
@ -598,7 +597,8 @@ gl_overbright_f (cvar_t *var)
|
|||
if (!gl_R_BuildLightMap)
|
||||
return;
|
||||
|
||||
for (ent = r_ent_queue[mod_brush]; ent; ent = ent->next) {
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_brush].size; i++) { \
|
||||
entity_t *ent = r_ent_queue->ent_queues[mod_brush].a[i]; \
|
||||
m = ent->renderer.model;
|
||||
if (m->path[0] == '*')
|
||||
continue;
|
||||
|
|
|
@ -193,8 +193,6 @@ gl_R_RotateForEntity (entity_t *e)
|
|||
static void
|
||||
R_DrawEntitiesOnList (void)
|
||||
{
|
||||
entity_t *ent;
|
||||
|
||||
if (!r_drawentities->int_val)
|
||||
return;
|
||||
|
||||
|
@ -220,7 +218,8 @@ R_DrawEntitiesOnList (void)
|
|||
qfglEnable (GL_NORMALIZE);
|
||||
}
|
||||
|
||||
for (ent = r_ent_queue[mod_alias]; ent; ent = ent->next) {
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_alias].size; i++) { \
|
||||
entity_t *ent = r_ent_queue->ent_queues[mod_alias].a[i]; \
|
||||
gl_R_DrawAliasModel (ent);
|
||||
}
|
||||
qfglColor3ubv (color_white);
|
||||
|
@ -248,7 +247,8 @@ R_DrawEntitiesOnList (void)
|
|||
qglActiveTexture (gl_mtex_enum + 0);
|
||||
}
|
||||
|
||||
for (ent = r_ent_queue[mod_iqm]; ent; ent = ent->next) {
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_iqm].size; i++) { \
|
||||
entity_t *ent = r_ent_queue->ent_queues[mod_iqm].a[i]; \
|
||||
gl_R_DrawIQMModel (ent);
|
||||
}
|
||||
qfglColor3ubv (color_white);
|
||||
|
@ -257,7 +257,8 @@ R_DrawEntitiesOnList (void)
|
|||
qfglEnable (GL_ALPHA_TEST);
|
||||
if (gl_va_capable)
|
||||
qfglInterleavedArrays (GL_T2F_C4UB_V3F, 0, gl_spriteVertexArray);
|
||||
for (ent = r_ent_queue[mod_sprite]; ent; ent = ent->next) {
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_sprite].size; i++) { \
|
||||
entity_t *ent = r_ent_queue->ent_queues[mod_sprite].a[i]; \
|
||||
R_DrawSpriteModel (ent);
|
||||
}
|
||||
qfglDisable (GL_ALPHA_TEST);
|
||||
|
@ -328,7 +329,7 @@ void
|
|||
gl_R_SetupFrame (void)
|
||||
{
|
||||
R_AnimateLight ();
|
||||
R_ClearEnts ();
|
||||
EntQueue_Clear (r_ent_queue);
|
||||
r_framecount++;
|
||||
|
||||
gl_Fog_SetupFrame ();
|
||||
|
|
|
@ -61,6 +61,8 @@
|
|||
#include "QF/GL/qf_textures.h"
|
||||
#include "QF/GL/qf_vid.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "mod_internal.h"
|
||||
#include "r_internal.h"
|
||||
#include "varrays.h"
|
||||
|
@ -140,6 +142,7 @@ gl_R_LoadSky_f (void)
|
|||
void
|
||||
gl_R_Init (void)
|
||||
{
|
||||
r_ent_queue = EntQueue_New (mod_num_types);
|
||||
R_Init_Cvars ();
|
||||
gl_R_Particles_Init_Cvars ();
|
||||
|
||||
|
@ -191,8 +194,6 @@ gl_R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
|
|||
r_worldentity.renderer.model = worldmodel;
|
||||
brush = &worldmodel->brush;
|
||||
|
||||
R_FreeAllEntities ();
|
||||
|
||||
// clear out efrags in case the level hasn't been reloaded
|
||||
for (unsigned i = 0; i < brush->modleafs; i++)
|
||||
brush->leafs[i].efrags = NULL;
|
||||
|
|
|
@ -740,8 +740,8 @@ gl_R_DrawWorld (void)
|
|||
|
||||
R_VisitWorldNodes (&bctx);
|
||||
if (r_drawentities->int_val) {
|
||||
entity_t *ent;
|
||||
for (ent = r_ent_queue[mod_brush]; ent; ent = ent->next) {
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_brush].size; i++) { \
|
||||
entity_t *ent = r_ent_queue->ent_queues[mod_brush].a[i]; \
|
||||
gl_R_DrawBrushModel (ent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1149,8 +1149,8 @@ glsl_R_DrawWorld (void)
|
|||
|
||||
R_VisitWorldNodes (&bctx);
|
||||
if (r_drawentities->int_val) {
|
||||
entity_t *ent;
|
||||
for (ent = r_ent_queue[mod_brush]; ent; ent = ent->next) {
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_brush].size; i++) {
|
||||
entity_t *ent = r_ent_queue->ent_queues[mod_brush].a[i];
|
||||
R_DrawBrushModel (ent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,8 @@
|
|||
#include "QF/screen.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "QF/GLSL/defines.h"
|
||||
#include "QF/GLSL/funcs.h"
|
||||
#include "QF/GLSL/qf_alias.h"
|
||||
|
@ -95,7 +97,7 @@ void
|
|||
glsl_R_SetupFrame (void)
|
||||
{
|
||||
R_AnimateLight ();
|
||||
R_ClearEnts ();
|
||||
EntQueue_Clear (r_ent_queue);
|
||||
r_framecount++;
|
||||
|
||||
VectorCopy (r_refdef.viewposition, r_origin);
|
||||
|
@ -141,7 +143,6 @@ R_SetupView (void)
|
|||
static void
|
||||
R_RenderEntities (void)
|
||||
{
|
||||
entity_t *ent;
|
||||
int begun;
|
||||
|
||||
if (!r_drawentities->int_val)
|
||||
|
@ -149,7 +150,9 @@ R_RenderEntities (void)
|
|||
#define RE_LOOP(type_name, Type) \
|
||||
do { \
|
||||
begun = 0; \
|
||||
for (ent = r_ent_queue[mod_##type_name]; ent; ent = ent->next) { \
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_##type_name].size; \
|
||||
i++) { \
|
||||
entity_t *ent = r_ent_queue->ent_queues[mod_##type_name].a[i]; \
|
||||
if (!begun) { \
|
||||
glsl_R_##Type##Begin (); \
|
||||
begun = 1; \
|
||||
|
@ -237,6 +240,7 @@ glsl_R_RenderView (void)
|
|||
void
|
||||
glsl_R_Init (void)
|
||||
{
|
||||
r_ent_queue = EntQueue_New (mod_num_types);
|
||||
Cmd_AddCommand ("timerefresh", glsl_R_TimeRefresh_f,
|
||||
"Test the current refresh rate for the current location.");
|
||||
R_Init_Cvars ();
|
||||
|
@ -267,7 +271,6 @@ glsl_R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
|
|||
r_viewleaf = NULL;
|
||||
R_MarkLeaves ();
|
||||
|
||||
R_FreeAllEntities ();
|
||||
R_ClearParticles ();
|
||||
glsl_R_RegisterTextures (models, num_models);
|
||||
glsl_R_BuildLightmaps (models, num_models);
|
||||
|
|
|
@ -235,11 +235,7 @@ R_StoreEfrags (const efrag_t *efrag)
|
|||
case mod_brush:
|
||||
case mod_sprite:
|
||||
case mod_iqm:
|
||||
if (ent->visibility.visframe != r_framecount) {
|
||||
R_EnqueueEntity (ent);
|
||||
// mark that we've recorded this entity for this frame
|
||||
ent->visibility.visframe = r_framecount;
|
||||
}
|
||||
EntQueue_AddEntity (r_ent_queue, ent, model->type);
|
||||
efrag = efrag->leafnext;
|
||||
break;
|
||||
|
||||
|
|
|
@ -48,100 +48,7 @@
|
|||
|
||||
#include "r_internal.h"
|
||||
|
||||
#define ENT_POOL_SIZE 32
|
||||
|
||||
typedef struct entity_pool_s {
|
||||
struct entity_pool_s *next;
|
||||
entity_t entities[ENT_POOL_SIZE];
|
||||
} entity_pool_t;
|
||||
|
||||
entity_t *r_ent_queue[mod_num_types];
|
||||
static entity_t **vis_tail[mod_num_types] = {
|
||||
[mod_brush] &r_ent_queue[mod_brush],
|
||||
[mod_sprite] &r_ent_queue[mod_sprite],
|
||||
[mod_alias] &r_ent_queue[mod_alias],
|
||||
[mod_iqm] &r_ent_queue[mod_iqm],
|
||||
};
|
||||
|
||||
static entity_pool_t *entity_pools = 0;
|
||||
static entity_pool_t **entpool_tail = &entity_pools;
|
||||
static entity_t *free_entities;
|
||||
|
||||
entity_t *
|
||||
R_AllocEntity (void)
|
||||
{
|
||||
entity_pool_t *pool;
|
||||
entity_t *ent;
|
||||
int i;
|
||||
|
||||
if ((ent = free_entities)) {
|
||||
free_entities = ent->next;
|
||||
ent->next = 0;
|
||||
ent->transform = 0;
|
||||
return ent;
|
||||
}
|
||||
|
||||
pool = malloc (sizeof (entity_pool_t));
|
||||
pool->next = 0;
|
||||
*entpool_tail = pool;
|
||||
entpool_tail = &pool->next;
|
||||
|
||||
for (ent = pool->entities, i = 0; i < ENT_POOL_SIZE - 1; i++, ent++) {
|
||||
ent->next = ent + 1;
|
||||
ent->transform = 0;
|
||||
}
|
||||
ent->next = 0;
|
||||
ent->transform = 0;
|
||||
free_entities = pool->entities;
|
||||
|
||||
return R_AllocEntity ();
|
||||
}
|
||||
|
||||
void
|
||||
R_FreeAllEntities (void)
|
||||
{
|
||||
entity_pool_t *pool;
|
||||
entity_t *ent;
|
||||
int i;
|
||||
|
||||
for (pool = entity_pools; pool; pool = pool->next) {
|
||||
for (ent = pool->entities, i = 0; i < ENT_POOL_SIZE - 1; i++, ent++) {
|
||||
ent->next = ent + 1;
|
||||
if (ent->transform) {
|
||||
Transform_Delete (ent->transform);
|
||||
ent->transform = 0;
|
||||
}
|
||||
}
|
||||
ent->next = pool->next ? pool->next->entities : 0;
|
||||
if (ent->transform) {
|
||||
Transform_Delete (ent->transform);
|
||||
ent->transform = 0;
|
||||
}
|
||||
}
|
||||
free_entities = entity_pools ? entity_pools->entities : 0;
|
||||
}
|
||||
|
||||
void
|
||||
R_ClearEnts (void)
|
||||
{
|
||||
for (int i = 0; i < mod_num_types; i++) {
|
||||
r_ent_queue[i] = 0;
|
||||
vis_tail[i] = &r_ent_queue[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
R_EnqueueEntity (entity_t *ent)
|
||||
{
|
||||
modtype_t type = ent->renderer.model->type;
|
||||
|
||||
if (type < 0 || type >= mod_num_types) {
|
||||
Sys_Error ("R_EnqueueEntity: Bad entity model type %d", type);
|
||||
}
|
||||
ent->next = 0;
|
||||
*vis_tail[type] = ent;
|
||||
vis_tail[type] = &ent->next;
|
||||
}
|
||||
entqueue_t *r_ent_queue;
|
||||
|
||||
float
|
||||
R_EntityBlend (animation_t *animation, int pose, float interval)
|
||||
|
|
|
@ -117,6 +117,8 @@ sw_R_Init (void)
|
|||
{
|
||||
int dummy;
|
||||
|
||||
r_ent_queue = EntQueue_New (mod_num_types);
|
||||
|
||||
// get stack position so we can guess if we are going to overflow
|
||||
r_stack_start = (byte *) & dummy;
|
||||
|
||||
|
@ -167,8 +169,6 @@ R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
|
|||
memset (&r_worldentity, 0, sizeof (r_worldentity));
|
||||
r_worldentity.renderer.model = worldmodel;
|
||||
|
||||
R_FreeAllEntities ();
|
||||
|
||||
// clear out efrags in case the level hasn't been reloaded
|
||||
for (unsigned i = 0; i < brush->modleafs; i++)
|
||||
brush->leafs[i].efrags = NULL;
|
||||
|
@ -418,14 +418,14 @@ draw_iqm_entity (entity_t *ent)
|
|||
static void
|
||||
R_DrawEntitiesOnList (void)
|
||||
{
|
||||
entity_t *ent;
|
||||
|
||||
if (!r_drawentities->int_val)
|
||||
return;
|
||||
|
||||
#define RE_LOOP(type_name) \
|
||||
do { \
|
||||
for (ent = r_ent_queue[mod_##type_name]; ent; ent = ent->next) { \
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_##type_name].size; \
|
||||
i++) { \
|
||||
entity_t *ent = r_ent_queue->ent_queues[mod_##type_name].a[i]; \
|
||||
VectorCopy (Transform_GetWorldPosition (ent->transform), \
|
||||
r_entorigin); \
|
||||
currententity = ent; \
|
||||
|
@ -566,7 +566,6 @@ R_DrawBEntitiesOnList (void)
|
|||
vec3_t origin;
|
||||
model_t *clmodel;
|
||||
float minmaxs[6];
|
||||
entity_t *ent;
|
||||
|
||||
if (!r_drawentities->int_val)
|
||||
return;
|
||||
|
@ -574,12 +573,12 @@ R_DrawBEntitiesOnList (void)
|
|||
VectorCopy (modelorg, oldorigin);
|
||||
insubmodel = true;
|
||||
|
||||
for (ent = r_ent_queue[mod_brush]; ent; ent = ent->next) {
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_brush].size; i++) {
|
||||
entity_t *ent = r_ent_queue->ent_queues[mod_brush].a[i];
|
||||
currententity = ent;
|
||||
|
||||
VectorCopy (Transform_GetWorldPosition (currententity->transform),
|
||||
origin);
|
||||
clmodel = currententity->renderer.model;
|
||||
VectorCopy (Transform_GetWorldPosition (ent->transform), origin);
|
||||
clmodel = ent->renderer.model;
|
||||
|
||||
// see if the bounding box lets us trivially reject, also
|
||||
// sets trivial accept status
|
||||
|
@ -626,8 +625,8 @@ R_DrawBEntitiesOnList (void)
|
|||
if (r_drawpolys | r_drawculledpolys) {
|
||||
R_ZDrawSubmodelPolys (clmodel);
|
||||
} else {
|
||||
if (currententity->visibility.topnode) {
|
||||
mnode_t *topnode = currententity->visibility.topnode;
|
||||
if (ent->visibility.topnode) {
|
||||
mnode_t *topnode = ent->visibility.topnode;
|
||||
|
||||
if (topnode->contents >= 0) {
|
||||
// not a leaf; has to be clipped to the world
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include "QF/sys.h"
|
||||
#include "QF/ui/view.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
|
@ -224,7 +226,7 @@ R_SetupFrame (void)
|
|||
R_CheckVariables ();
|
||||
|
||||
R_AnimateLight ();
|
||||
R_ClearEnts ();
|
||||
EntQueue_Clear (r_ent_queue);
|
||||
r_framecount++;
|
||||
|
||||
numbtofpolys = 0;
|
||||
|
|
|
@ -142,6 +142,8 @@ sw32_R_Init (void)
|
|||
{
|
||||
int dummy;
|
||||
|
||||
r_ent_queue = EntQueue_New (mod_num_types);
|
||||
|
||||
// get stack position so we can guess if we are going to overflow
|
||||
r_stack_start = (byte *) & dummy;
|
||||
|
||||
|
@ -182,8 +184,6 @@ sw32_R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
|
|||
memset (&r_worldentity, 0, sizeof (r_worldentity));
|
||||
r_worldentity.renderer.model = worldmodel;
|
||||
|
||||
R_FreeAllEntities ();
|
||||
|
||||
// clear out efrags in case the level hasn't been reloaded
|
||||
for (unsigned i = 0; i < brush->modleafs; i++)
|
||||
brush->leafs[i].efrags = NULL;
|
||||
|
@ -425,14 +425,14 @@ draw_iqm_entity (entity_t *ent)
|
|||
static void
|
||||
R_DrawEntitiesOnList (void)
|
||||
{
|
||||
entity_t *ent;
|
||||
|
||||
if (!r_drawentities->int_val)
|
||||
return;
|
||||
|
||||
#define RE_LOOP(type_name) \
|
||||
do { \
|
||||
for (ent = r_ent_queue[mod_##type_name]; ent; ent = ent->next) { \
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_##type_name].size; \
|
||||
i++) { \
|
||||
entity_t *ent = r_ent_queue->ent_queues[mod_##type_name].a[i]; \
|
||||
VectorCopy (Transform_GetWorldPosition (ent->transform), \
|
||||
r_entorigin); \
|
||||
currententity = ent; \
|
||||
|
@ -572,7 +572,6 @@ R_DrawBEntitiesOnList (void)
|
|||
vec3_t origin;
|
||||
model_t *clmodel;
|
||||
float minmaxs[6];
|
||||
entity_t *ent;
|
||||
|
||||
if (!r_drawentities->int_val)
|
||||
return;
|
||||
|
@ -580,12 +579,12 @@ R_DrawBEntitiesOnList (void)
|
|||
VectorCopy (modelorg, oldorigin);
|
||||
insubmodel = true;
|
||||
|
||||
for (ent = r_ent_queue[mod_brush]; ent; ent = ent->next) {
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_brush].size; i++) {
|
||||
entity_t *ent = r_ent_queue->ent_queues[mod_brush].a[i];
|
||||
currententity = ent;
|
||||
|
||||
VectorCopy (Transform_GetWorldPosition (currententity->transform),
|
||||
origin);
|
||||
clmodel = currententity->renderer.model;
|
||||
VectorCopy (Transform_GetWorldPosition (ent->transform), origin);
|
||||
clmodel = ent->renderer.model;
|
||||
|
||||
// see if the bounding box lets us trivially reject, also
|
||||
// sets trivial accept status
|
||||
|
@ -632,8 +631,8 @@ R_DrawBEntitiesOnList (void)
|
|||
if (sw32_r_drawpolys | sw32_r_drawculledpolys) {
|
||||
sw32_R_ZDrawSubmodelPolys (clmodel);
|
||||
} else {
|
||||
if (currententity->visibility.topnode) {
|
||||
mnode_t *topnode = currententity->visibility.topnode;
|
||||
if (ent->visibility.topnode) {
|
||||
mnode_t *topnode = ent->visibility.topnode;
|
||||
|
||||
if (topnode->contents >= 0) {
|
||||
// not a leaf; has to be clipped to the world
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#include "QF/sys.h"
|
||||
#include "QF/ui/view.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
|
@ -220,7 +222,7 @@ sw32_R_SetupFrame (void)
|
|||
R_CheckVariables ();
|
||||
|
||||
R_AnimateLight ();
|
||||
R_ClearEnts ();
|
||||
EntQueue_Clear (r_ent_queue);
|
||||
r_framecount++;
|
||||
|
||||
sw32_numbtofpolys = 0;
|
||||
|
|
|
@ -152,7 +152,6 @@ vid_render_funcs_t gl_vid_render_funcs = {
|
|||
R_RemoveEfrags,
|
||||
gl_R_LineGraph,
|
||||
R_AllocDlight,
|
||||
R_AllocEntity,
|
||||
R_MaxDlightsCheck,
|
||||
R_DecayLights,
|
||||
gl_R_ViewChanged,
|
||||
|
|
|
@ -151,7 +151,6 @@ vid_render_funcs_t glsl_vid_render_funcs = {
|
|||
R_RemoveEfrags,
|
||||
glsl_R_LineGraph,
|
||||
R_AllocDlight,
|
||||
R_AllocEntity,
|
||||
R_MaxDlightsCheck,
|
||||
R_DecayLights,
|
||||
glsl_R_ViewChanged,
|
||||
|
|
|
@ -148,7 +148,6 @@ vid_render_funcs_t sw_vid_render_funcs = {
|
|||
R_RemoveEfrags,
|
||||
R_LineGraph,
|
||||
R_AllocDlight,
|
||||
R_AllocEntity,
|
||||
R_MaxDlightsCheck,
|
||||
R_DecayLights,
|
||||
R_ViewChanged,
|
||||
|
|
|
@ -153,7 +153,6 @@ vid_render_funcs_t sw32_vid_render_funcs = {
|
|||
R_RemoveEfrags,
|
||||
sw32_R_LineGraph,
|
||||
R_AllocDlight,
|
||||
R_AllocEntity,
|
||||
R_MaxDlightsCheck,
|
||||
R_DecayLights,
|
||||
sw32_R_ViewChanged,
|
||||
|
|
|
@ -61,6 +61,8 @@
|
|||
#include "QF/Vulkan/swapchain.h"
|
||||
#include "QF/ui/view.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "mod_internal.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
|
@ -100,6 +102,7 @@ vulkan_ParticleSystem (void)
|
|||
static void
|
||||
vulkan_R_Init (void)
|
||||
{
|
||||
r_ent_queue = EntQueue_New (mod_num_types);
|
||||
Vulkan_CreateStagingBuffers (vulkan_ctx);
|
||||
Vulkan_CreateSwapchain (vulkan_ctx);
|
||||
Vulkan_CreateFrames (vulkan_ctx);
|
||||
|
@ -679,7 +682,6 @@ vid_render_funcs_t vulkan_vid_render_funcs = {
|
|||
R_RemoveEfrags,
|
||||
vulkan_R_LineGraph,
|
||||
R_AllocDlight,
|
||||
R_AllocEntity,
|
||||
R_MaxDlightsCheck,
|
||||
R_DecayLights,
|
||||
vulkan_R_ViewChanged,
|
||||
|
|
|
@ -1039,8 +1039,8 @@ Vulkan_DrawWorld (qfv_renderframe_t *rFrame)
|
|||
|
||||
R_VisitWorldNodes (brush, ctx);
|
||||
if (r_drawentities->int_val) {
|
||||
entity_t *ent;
|
||||
for (ent = r_ent_queue[mod_brush]; ent; ent = ent->next) {
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_brush].size; i++) {
|
||||
entity_t *ent = r_ent_queue->ent_queues[mod_brush].a[i];
|
||||
R_DrawBrushModel (ent, ctx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#include "QF/screen.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "QF/Vulkan/qf_vid.h"
|
||||
#include "QF/Vulkan/qf_alias.h"
|
||||
#include "QF/Vulkan/qf_bsp.h"
|
||||
|
@ -65,7 +67,7 @@ static void
|
|||
setup_frame (vulkan_ctx_t *ctx)
|
||||
{
|
||||
R_AnimateLight ();
|
||||
R_ClearEnts ();
|
||||
EntQueue_Clear (r_ent_queue);
|
||||
r_framecount++;
|
||||
|
||||
VectorCopy (r_refdef.viewposition, r_origin);
|
||||
|
@ -85,9 +87,10 @@ Vulkan_RenderEntities (qfv_renderframe_t *rFrame)
|
|||
return;
|
||||
#define RE_LOOP(type_name, Type) \
|
||||
do { \
|
||||
entity_t *ent; \
|
||||
int begun = 0; \
|
||||
for (ent = r_ent_queue[mod_##type_name]; ent; ent = ent->next) { \
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_##type_name].size; \
|
||||
i++) { \
|
||||
entity_t *ent = r_ent_queue->ent_queues[mod_##type_name].a[i]; \
|
||||
if (!begun) { \
|
||||
Vulkan_##Type##Begin (rFrame); \
|
||||
begun = 1; \
|
||||
|
@ -122,7 +125,7 @@ Vulkan_DrawViewModel (vulkan_ctx_t *ctx)
|
|||
|| !ent->renderer.model)
|
||||
return;
|
||||
|
||||
R_EnqueueEntity (ent);
|
||||
EntQueue_AddEntity (r_ent_queue, ent, ent->renderer.model->type);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -195,7 +198,6 @@ Vulkan_NewMap (model_t *worldmodel, struct model_s **models, int num_models,
|
|||
r_viewleaf = NULL;
|
||||
R_MarkLeaves ();
|
||||
|
||||
R_FreeAllEntities ();
|
||||
R_ClearParticles ();
|
||||
Vulkan_RegisterTextures (models, num_models, ctx);
|
||||
//Vulkan_BuildLightmaps (models, num_models, ctx);
|
||||
|
|
|
@ -180,14 +180,9 @@ typedef struct client_state_s {
|
|||
|
||||
/* information that is static for the entire time connected to a server */
|
||||
|
||||
struct model_s *model_precache[MAX_MODELS];
|
||||
struct sfx_s *sound_precache[MAX_SOUNDS];
|
||||
int nummodels;
|
||||
int numsounds;
|
||||
|
||||
struct plitem_s *edicts;
|
||||
struct plitem_s *worldspawn;
|
||||
|
||||
char levelname[40]; // for display on solo scoreboard
|
||||
int spectator;
|
||||
int playernum;
|
||||
|
@ -205,9 +200,7 @@ typedef struct client_state_s {
|
|||
int fbskins;
|
||||
|
||||
// refresh related state
|
||||
struct model_s *worldmodel; // cl_entitites[0].model
|
||||
int num_entities; // held in cl_entities array
|
||||
entity_t viewent; // the weapon model
|
||||
|
||||
int cdtrack; // cd audio
|
||||
|
||||
|
@ -240,10 +233,9 @@ extern struct cvar_s *noskins;
|
|||
|
||||
extern client_state_t cl;
|
||||
|
||||
// FIXME, allocate dynamically
|
||||
extern entity_t cl_entities[MAX_EDICTS];
|
||||
extern entity_t *cl_entities[MAX_EDICTS];
|
||||
extern double cl_msgtime[MAX_EDICTS];
|
||||
extern byte cl_forcelink[MAX_EDICTS];
|
||||
extern struct set_s cl_forcelink;
|
||||
|
||||
extern int fps_count;
|
||||
|
||||
|
@ -299,6 +291,7 @@ void CL_NewTranslation (int slot, struct skin_s *skin);
|
|||
void CL_SignonReply (void);
|
||||
void CL_RelinkEntities (void);
|
||||
void CL_ClearEnts (void);
|
||||
entity_t *CL_GetEntity (int num);
|
||||
|
||||
extern double realtime;
|
||||
|
||||
|
|
|
@ -48,6 +48,8 @@
|
|||
|
||||
#include "compat.h"
|
||||
|
||||
#include "client/world.h"
|
||||
|
||||
#include "nq/include/client.h"
|
||||
#include "nq/include/host.h"
|
||||
|
||||
|
@ -338,8 +340,8 @@ demo_default_name (const char *argv1)
|
|||
time (&tim);
|
||||
strftime (timestring, 19, "%Y-%m-%d-%H-%M", localtime (&tim));
|
||||
|
||||
// the leading path-name is to be removed from cl.worldmodel->name
|
||||
mapname = QFS_SkipPath (cl.worldmodel->path);
|
||||
// the leading path-name is to be removed from cl_world.worldmodel->name
|
||||
mapname = QFS_SkipPath (cl_world.worldmodel->path);
|
||||
|
||||
// the map name is cut off after any "." because this would prevent
|
||||
// an extension being appended
|
||||
|
|
|
@ -44,11 +44,13 @@
|
|||
|
||||
#include "QF/plugin/vid_render.h"
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/scene.h"
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#include "client/effects.h"
|
||||
#include "client/temp_entities.h"
|
||||
#include "client/world.h"
|
||||
|
||||
#include "client/chase.h"
|
||||
|
||||
|
@ -57,9 +59,12 @@
|
|||
#include "nq/include/host.h"
|
||||
#include "nq/include/server.h"
|
||||
|
||||
entity_t cl_entities[MAX_EDICTS];
|
||||
double cl_msgtime[MAX_EDICTS];
|
||||
byte cl_forcelink[MAX_EDICTS];
|
||||
entity_t *cl_entities[MAX_EDICTS];
|
||||
double cl_msgtime[MAX_EDICTS];
|
||||
static byte forcelink_bytes[SET_SIZE(MAX_EDICTS)];
|
||||
#define alloc_forcelink(s) (set_bits_t *)forcelink_bytes
|
||||
set_t cl_forcelink = SET_STATIC_INIT (MAX_EDICTS, alloc_forcelink);
|
||||
#undef alloc_forcelink
|
||||
|
||||
void
|
||||
CL_ClearEnts (void)
|
||||
|
@ -67,14 +72,27 @@ CL_ClearEnts (void)
|
|||
size_t i;
|
||||
|
||||
for (i = 0; i < MAX_EDICTS; i++) {
|
||||
CL_Init_Entity (cl_entities + i);
|
||||
if (cl_entities[i]) {
|
||||
Scene_DestroyEntity (cl_world.scene, cl_entities[i]);
|
||||
cl_entities[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// clear other arrays
|
||||
i = nq_entstates.num_frames * nq_entstates.num_entities;
|
||||
memset (nq_entstates.frame[0], 0, i * sizeof (entity_state_t));
|
||||
memset (cl_msgtime, 0, sizeof (cl_msgtime));
|
||||
memset (cl_forcelink, 0, sizeof (cl_forcelink));
|
||||
set_empty (&cl_forcelink);
|
||||
}
|
||||
|
||||
entity_t *
|
||||
CL_GetEntity (int num)
|
||||
{
|
||||
if (!cl_entities[num]) {
|
||||
cl_entities[num] = Scene_CreateEntity (cl_world.scene);
|
||||
CL_Init_Entity (cl_entities[num]);
|
||||
}
|
||||
return cl_entities[num];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -115,12 +133,12 @@ CL_LerpPoint (void)
|
|||
}
|
||||
|
||||
static void
|
||||
set_entity_model (entity_t *ent, int modelindex)
|
||||
set_entity_model (int ent_ind, int modelindex)
|
||||
{
|
||||
int i = ent - cl_entities;
|
||||
entity_t *ent = cl_entities[ent_ind];
|
||||
renderer_t *renderer = &ent->renderer;
|
||||
animation_t *animation = &ent->animation;
|
||||
renderer->model = cl.model_precache[modelindex];
|
||||
renderer->model = cl_world.models.a[modelindex];
|
||||
// automatic animation (torches, etc) can be either all together
|
||||
// or randomized
|
||||
if (renderer->model) {
|
||||
|
@ -130,11 +148,12 @@ set_entity_model (entity_t *ent, int modelindex)
|
|||
animation->syncbase = 0.0;
|
||||
}
|
||||
} else {
|
||||
cl_forcelink[i] = true; // hack to make null model players work
|
||||
// hack to make null model players work
|
||||
SET_ADD (&cl_forcelink, ent_ind);
|
||||
}
|
||||
animation->nolerp = 1; // don't try to lerp when the model has changed
|
||||
if (i <= cl.maxclients) {
|
||||
renderer->skin = mod_funcs->Skin_SetColormap (renderer->skin, i);
|
||||
if (ent_ind <= cl.maxclients) {
|
||||
renderer->skin = mod_funcs->Skin_SetColormap (renderer->skin, ent_ind);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,8 +169,6 @@ CL_RelinkEntities (void)
|
|||
int entvalid;
|
||||
int model_flags;
|
||||
|
||||
r_data->player_entity = &cl_entities[cl.viewentity];
|
||||
|
||||
// determine partial update time
|
||||
frac = CL_LerpPoint ();
|
||||
|
||||
|
@ -180,7 +197,7 @@ CL_RelinkEntities (void)
|
|||
for (i = 1; i < cl.num_entities; i++) {
|
||||
new = &nq_entstates.frame[0 + cl.frameIndex][i];
|
||||
old = &nq_entstates.frame[1 - cl.frameIndex][i];
|
||||
ent = &cl_entities[i];
|
||||
ent = CL_GetEntity (i);
|
||||
renderer = &ent->renderer;
|
||||
animation = &ent->animation;
|
||||
|
||||
|
@ -200,20 +217,24 @@ CL_RelinkEntities (void)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cl_forcelink[i])
|
||||
if (SET_TEST_MEMBER (&cl_forcelink, i)) {
|
||||
*old = *new;
|
||||
}
|
||||
|
||||
if (cl_forcelink[i] || new->modelindex != old->modelindex) {
|
||||
if (SET_TEST_MEMBER (&cl_forcelink, i)
|
||||
|| new->modelindex != old->modelindex) {
|
||||
old->modelindex = new->modelindex;
|
||||
set_entity_model (ent, new->modelindex);
|
||||
set_entity_model (i, new->modelindex);
|
||||
}
|
||||
animation->frame = new->frame;
|
||||
if (cl_forcelink[i] || new->colormap != old->colormap) {
|
||||
if (SET_TEST_MEMBER (&cl_forcelink, i)
|
||||
|| new->colormap != old->colormap) {
|
||||
old->colormap = new->colormap;
|
||||
renderer->skin = mod_funcs->Skin_SetColormap (renderer->skin,
|
||||
new->colormap);
|
||||
}
|
||||
if (cl_forcelink[i] || new->skinnum != old->skinnum) {
|
||||
if (SET_TEST_MEMBER (&cl_forcelink, i)
|
||||
|| new->skinnum != old->skinnum) {
|
||||
old->skinnum = new->skinnum;
|
||||
renderer->skinnum = new->skinnum;
|
||||
if (i <= cl.maxclients) {
|
||||
|
@ -232,7 +253,7 @@ CL_RelinkEntities (void)
|
|||
model_flags = renderer->model->flags;
|
||||
}
|
||||
|
||||
if (cl_forcelink[i]) {
|
||||
if (SET_TEST_MEMBER (&cl_forcelink, i)) {
|
||||
// The entity was not updated in the last message so move to the
|
||||
// final spot
|
||||
animation->pose1 = animation->pose2 = -1;
|
||||
|
@ -242,7 +263,7 @@ CL_RelinkEntities (void)
|
|||
if (ent->visibility.efrag) {
|
||||
r_funcs->R_RemoveEfrags (ent);
|
||||
}
|
||||
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
|
||||
r_funcs->R_AddEfrags (&cl_world.worldmodel->brush, ent);
|
||||
}
|
||||
ent->old_origin = new->origin;
|
||||
} else {
|
||||
|
@ -278,10 +299,10 @@ CL_RelinkEntities (void)
|
|||
= Transform_GetWorldPosition (ent->transform);
|
||||
if (!VectorCompare (org, ent->old_origin)) {//FIXME
|
||||
r_funcs->R_RemoveEfrags (ent);
|
||||
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
|
||||
r_funcs->R_AddEfrags (&cl_world.worldmodel->brush, ent);
|
||||
}
|
||||
} else {
|
||||
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
|
||||
r_funcs->R_AddEfrags (&cl_world.worldmodel->brush, ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -303,8 +324,10 @@ CL_RelinkEntities (void)
|
|||
if (model_flags & ~EF_ROTATE)
|
||||
CL_ModelEffects (ent, i, new->glow_color, cl.time);
|
||||
|
||||
cl_forcelink[i] = false;
|
||||
SET_REMOVE (&cl_forcelink, i);
|
||||
}
|
||||
r_data->player_entity = CL_GetEntity (cl.viewentity);
|
||||
cl.viewstate.player_entity = CL_GetEntity (cl.viewentity);
|
||||
cl.viewstate.player_origin
|
||||
= Transform_GetWorldPosition (cl_entities[cl.viewentity].transform);
|
||||
= Transform_GetWorldPosition (cl.viewstate.player_entity->transform);
|
||||
}
|
||||
|
|
|
@ -48,14 +48,16 @@
|
|||
#include "QF/plugin/console.h"
|
||||
#include "QF/plugin/vid_render.h"
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/scene.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "sbar.h"
|
||||
|
||||
#include "client/chase.h"
|
||||
#include "client/particles.h"
|
||||
#include "client/temp_entities.h"
|
||||
#include "client/world.h"
|
||||
|
||||
#include "client/chase.h"
|
||||
#include "nq/include/cl_skin.h"
|
||||
#include "nq/include/client.h"
|
||||
#include "nq/include/host.h"
|
||||
|
@ -188,9 +190,9 @@ CL_ClearState (void)
|
|||
if (!sv.active)
|
||||
Host_ClearMemory ();
|
||||
|
||||
if (cl.edicts)
|
||||
PL_Free (cl.edicts);
|
||||
|
||||
if (cl.viewstate.weapon_entity) {
|
||||
Scene_DestroyEntity (cl_world.scene, cl.viewstate.weapon_entity);
|
||||
}
|
||||
if (cl.players) {
|
||||
int i;
|
||||
|
||||
|
@ -202,6 +204,7 @@ CL_ClearState (void)
|
|||
__auto_type cam = cl.viewstate.camera_transform;
|
||||
memset (&cl, 0, sizeof (cl));
|
||||
cl.viewstate.camera_transform = cam;
|
||||
|
||||
cl.viewstate.player_origin = (vec4f_t) {0, 0, 0, 1};
|
||||
cl.viewstate.chase = 1;
|
||||
cl.viewstate.chasestate = &cl.chasestate;
|
||||
|
@ -210,10 +213,6 @@ CL_ClearState (void)
|
|||
r_data->force_fullscreen = 0;
|
||||
r_data->lightstyle = cl.lightstyle;
|
||||
|
||||
CL_Init_Entity (&cl.viewent);
|
||||
cl.viewstate.weapon_entity = &cl.viewent;
|
||||
r_data->view_model = &cl.viewent;
|
||||
|
||||
SZ_Clear (&cls.message);
|
||||
|
||||
CL_ClearTEnts ();
|
||||
|
@ -221,6 +220,10 @@ CL_ClearState (void)
|
|||
r_funcs->R_ClearState ();
|
||||
|
||||
CL_ClearEnts ();
|
||||
|
||||
cl.viewstate.weapon_entity = Scene_CreateEntity (cl_world.scene);
|
||||
CL_Init_Entity (cl.viewstate.weapon_entity);
|
||||
r_data->view_model = cl.viewstate.weapon_entity;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -276,7 +279,7 @@ CL_Disconnect (void)
|
|||
Host_ShutdownServer (false);
|
||||
}
|
||||
|
||||
cl.worldmodel = NULL;
|
||||
cl_world.worldmodel = NULL;
|
||||
cl.intermission = 0;
|
||||
cl.viewstate.intermission = 0;
|
||||
}
|
||||
|
@ -389,18 +392,18 @@ CL_NextDemo (void)
|
|||
static void
|
||||
pointfile_f (void)
|
||||
{
|
||||
CL_LoadPointFile (cl.worldmodel);
|
||||
CL_LoadPointFile (cl_world.worldmodel);
|
||||
}
|
||||
|
||||
static void
|
||||
CL_PrintEntities_f (void)
|
||||
{
|
||||
entity_t *ent;
|
||||
int i;
|
||||
|
||||
for (i = 0, ent = cl_entities; i < cl.num_entities; i++, ent++) {
|
||||
for (i = 0; i < cl.num_entities; i++) {
|
||||
entity_t *ent = cl_entities[i];
|
||||
Sys_Printf ("%3i:", i);
|
||||
if (!ent->renderer.model) {
|
||||
if (!ent || !ent->renderer.model) {
|
||||
Sys_Printf ("EMPTY\n");
|
||||
continue;
|
||||
}
|
||||
|
@ -422,8 +425,8 @@ CL_ReadFromServer (void)
|
|||
{
|
||||
int ret;
|
||||
TEntContext_t tentCtx = {
|
||||
Transform_GetWorldPosition (cl_entities[cl.viewentity].transform),
|
||||
cl.worldmodel, cl.viewentity
|
||||
cl.viewstate.player_origin,
|
||||
cl.viewentity
|
||||
};
|
||||
|
||||
cl.oldtime = cl.time;
|
||||
|
@ -571,6 +574,7 @@ CL_Init (cbuf_t *cbuf)
|
|||
CL_Init_Input (cbuf);
|
||||
CL_Particles_Init ();
|
||||
CL_TEnts_Init ();
|
||||
CL_World_Init ();
|
||||
CL_ClearState ();
|
||||
|
||||
V_Init (&cl.viewstate);
|
||||
|
|
|
@ -51,10 +51,13 @@
|
|||
#include "QF/sound.h" // FIXME: DEFAULT_SOUND_PACKET_*
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "QF/scene/scene.h"
|
||||
|
||||
#include "QF/plugin/vid_render.h"
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "client/temp_entities.h"
|
||||
#include "client/world.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "sbar.h"
|
||||
|
@ -125,24 +128,6 @@ const char *svc_strings[] = {
|
|||
|
||||
dstring_t *centerprint;
|
||||
|
||||
static void
|
||||
CL_LoadSky (void)
|
||||
{
|
||||
plitem_t *item;
|
||||
const char *name = 0;
|
||||
|
||||
if (!cl.worldspawn) {
|
||||
r_funcs->R_LoadSkys (0);
|
||||
return;
|
||||
}
|
||||
if ((item = PL_ObjectForKey (cl.worldspawn, "sky")) // Q2/DarkPlaces
|
||||
|| (item = PL_ObjectForKey (cl.worldspawn, "skyname")) // old QF
|
||||
|| (item = PL_ObjectForKey (cl.worldspawn, "qlsky"))) /* QuakeLives */ {
|
||||
name = PL_String (item);
|
||||
}
|
||||
r_funcs->R_LoadSkys (name);
|
||||
}
|
||||
|
||||
/*
|
||||
CL_EntityNum
|
||||
|
||||
|
@ -263,72 +248,13 @@ CL_KeepaliveMessage (void)
|
|||
SZ_Clear (&cls.message);
|
||||
}
|
||||
|
||||
static void
|
||||
map_cfg (const char *mapname, int all)
|
||||
{
|
||||
char *name = malloc (strlen (mapname) + 4 + 1);
|
||||
cbuf_t *cbuf = Cbuf_New (&id_interp);
|
||||
QFile *f;
|
||||
|
||||
QFS_StripExtension (mapname, name);
|
||||
strcat (name, ".cfg");
|
||||
f = QFS_FOpenFile (name);
|
||||
if (f) {
|
||||
Qclose (f);
|
||||
Cmd_Exec_File (cbuf, name, 1);
|
||||
} else {
|
||||
Cmd_Exec_File (cbuf, "maps_default.cfg", 1);
|
||||
}
|
||||
if (all) {
|
||||
Cbuf_Execute_Stack (cbuf);
|
||||
} else {
|
||||
Cbuf_Execute_Sets (cbuf);
|
||||
}
|
||||
free (name);
|
||||
Cbuf_Delete (cbuf);
|
||||
}
|
||||
|
||||
static plitem_t *
|
||||
map_ent (const char *mapname)
|
||||
{
|
||||
static progs_t edpr;
|
||||
char *name = malloc (strlen (mapname) + 4 + 1);
|
||||
char *buf;
|
||||
plitem_t *edicts = 0;
|
||||
QFile *ent_file;
|
||||
|
||||
QFS_StripExtension (mapname, name);
|
||||
strcat (name, ".ent");
|
||||
ent_file = QFS_VOpenFile (name, 0, cl.model_precache[1]->vpath);
|
||||
if ((buf = (char *) QFS_LoadFile (ent_file, 0))) {
|
||||
edicts = ED_Parse (&edpr, buf);
|
||||
free (buf);
|
||||
} else {
|
||||
edicts = ED_Parse (&edpr, cl.model_precache[1]->brush.entities);
|
||||
}
|
||||
free (name);
|
||||
return edicts;
|
||||
}
|
||||
|
||||
static void
|
||||
CL_NewMap (const char *mapname)
|
||||
{
|
||||
r_funcs->R_NewMap (cl.worldmodel, cl.model_precache, cl.nummodels);
|
||||
Con_NewMap ();
|
||||
Hunk_Check (0); // make sure nothing is hurt
|
||||
Sbar_CenterPrint (0);
|
||||
|
||||
if (cl.model_precache[1] && cl.model_precache[1]->brush.entities) {
|
||||
cl.edicts = map_ent (mapname);
|
||||
if (cl.edicts) {
|
||||
cl.worldspawn = PL_ObjectAtIndex (cl.edicts, 0);
|
||||
CL_LoadSky ();
|
||||
if (r_funcs->Fog_ParseWorldspawn)
|
||||
r_funcs->Fog_ParseWorldspawn (cl.worldspawn);
|
||||
}
|
||||
}
|
||||
|
||||
map_cfg (mapname, 1);
|
||||
CL_World_NewMap (mapname, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -338,6 +264,7 @@ CL_ParseServerInfo (void)
|
|||
char sound_precache[MAX_SOUNDS][MAX_QPATH];
|
||||
const char *str;
|
||||
int i;
|
||||
int nummodels;
|
||||
|
||||
Sys_MaskPrintf (SYS_dev, "Serverinfo packet received.\n");
|
||||
|
||||
|
@ -394,16 +321,17 @@ CL_ParseServerInfo (void)
|
|||
// needlessly purge it
|
||||
|
||||
// precache models
|
||||
memset (cl.model_precache, 0, sizeof (cl.model_precache));
|
||||
for (cl.nummodels = 1;; cl.nummodels++) {
|
||||
cl_world.models.size = 0;
|
||||
DARRAY_APPEND (&cl_world.models, 0); // ind 0 is null model
|
||||
for (nummodels = 1;; nummodels++) {
|
||||
str = MSG_ReadString (net_message);
|
||||
if (!str[0])
|
||||
break;
|
||||
if (cl.nummodels >= MAX_MODELS) {
|
||||
if (nummodels >= MAX_MODELS) {
|
||||
Sys_Printf ("Server sent too many model precaches\n");
|
||||
goto done;
|
||||
}
|
||||
strcpy (model_precache[cl.nummodels], str);
|
||||
strcpy (model_precache[nummodels], str);
|
||||
Mod_TouchModel (str);
|
||||
}
|
||||
|
||||
|
@ -421,12 +349,12 @@ CL_ParseServerInfo (void)
|
|||
}
|
||||
|
||||
// now we try to load everything else until a cache allocation fails
|
||||
if (model_precache[1])
|
||||
map_cfg (model_precache[1], 0);
|
||||
CL_MapCfg (model_precache[1]);
|
||||
|
||||
for (i = 1; i < cl.nummodels; i++) {
|
||||
cl.model_precache[i] = Mod_ForName (model_precache[i], false);
|
||||
if (cl.model_precache[i] == NULL) {
|
||||
for (i = 1; i < nummodels; i++) {
|
||||
DARRAY_APPEND (&cl_world.models,
|
||||
Mod_ForName (model_precache[i], false));
|
||||
if (cl_world.models.a[i] == NULL) {
|
||||
Sys_Printf ("Model %s not found\n", model_precache[i]);
|
||||
goto done;
|
||||
}
|
||||
|
@ -439,8 +367,8 @@ CL_ParseServerInfo (void)
|
|||
}
|
||||
|
||||
// local state
|
||||
cl_entities[0].renderer.model = cl.worldmodel = cl.model_precache[1];
|
||||
cl.chasestate.worldmodel = cl.worldmodel;
|
||||
cl_world.worldmodel = cl_world.models.a[1];
|
||||
cl.chasestate.worldmodel = cl_world.worldmodel;
|
||||
if (!centerprint)
|
||||
centerprint = dstring_newstr ();
|
||||
else
|
||||
|
@ -600,44 +528,10 @@ CL_ParseUpdate (int bits)
|
|||
//VectorCopy (state->msg_angles[0], state->msg_angles[1]);
|
||||
//CL_TransformEntity (ent, state->msg_angles[0]);
|
||||
//state->forcelink = true;
|
||||
cl_forcelink[num] = true;
|
||||
SET_ADD (&cl_forcelink, num);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
CL_ParseBaseline (entity_state_t *baseline, int version)
|
||||
{
|
||||
int bits = 0;
|
||||
|
||||
if (version == 2)
|
||||
bits = MSG_ReadByte (net_message);
|
||||
|
||||
if (bits & B_LARGEMODEL)
|
||||
baseline->modelindex = MSG_ReadShort (net_message);
|
||||
else
|
||||
baseline->modelindex = MSG_ReadByte (net_message);
|
||||
|
||||
if (bits & B_LARGEFRAME)
|
||||
baseline->frame = MSG_ReadShort (net_message);
|
||||
else
|
||||
baseline->frame = MSG_ReadByte (net_message);
|
||||
|
||||
baseline->colormap = MSG_ReadByte (net_message);
|
||||
baseline->skinnum = MSG_ReadByte (net_message);
|
||||
|
||||
MSG_ReadCoordAngleV (net_message, &baseline->origin[0], baseline->angles);
|
||||
baseline->origin[3] = 1;//FIXME
|
||||
|
||||
if (bits & B_ALPHA)
|
||||
baseline->alpha = MSG_ReadByte (net_message);
|
||||
else
|
||||
baseline->alpha = 255;//FIXME alpha
|
||||
baseline->scale = 16;
|
||||
baseline->glow_size = 0;
|
||||
baseline->glow_color = 254;
|
||||
baseline->colormod = 255;
|
||||
}
|
||||
|
||||
/*
|
||||
CL_ParseClientdata
|
||||
|
||||
|
@ -723,7 +617,7 @@ CL_ParseClientdata (void)
|
|||
if (cl.stats[STAT_WEAPON] != i) {
|
||||
cl.stats[STAT_WEAPON] = i;
|
||||
Sbar_Changed ();
|
||||
cl.viewstate.weapon_model = cl.model_precache[cl.stats[STAT_WEAPON]];
|
||||
cl.viewstate.weapon_model = cl_world.models.a[cl.stats[STAT_WEAPON]];
|
||||
}
|
||||
|
||||
i = (short) MSG_ReadShort (net_message);
|
||||
|
@ -779,38 +673,13 @@ CL_ParseClientdata (void)
|
|||
cl.stats[STAT_WEAPONFRAME] |= MSG_ReadByte (net_message) << 8;
|
||||
if (bits & SU_WEAPONALPHA) {
|
||||
byte alpha = MSG_ReadByte (net_message);
|
||||
cl.viewent.renderer.colormod[3] = ENTALPHA_DECODE (alpha);
|
||||
float a = ENTALPHA_DECODE (alpha);
|
||||
cl.viewstate.weapon_entity->renderer.colormod[3] = a;
|
||||
} else {
|
||||
cl.viewent.renderer.colormod[3] = 1.0;
|
||||
cl.viewstate.weapon_entity->renderer.colormod[3] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
CL_ParseStatic (int version)
|
||||
{
|
||||
entity_state_t baseline;
|
||||
entity_t *ent;
|
||||
|
||||
ent = r_funcs->R_AllocEntity ();
|
||||
CL_Init_Entity (ent);
|
||||
|
||||
CL_ParseBaseline (&baseline, version);
|
||||
|
||||
// copy it to the current state
|
||||
//FIXME alpha & lerp
|
||||
ent->renderer.model = cl.model_precache[baseline.modelindex];
|
||||
ent->animation.frame = baseline.frame;
|
||||
ent->renderer.skin = 0;
|
||||
ent->renderer.skinnum = baseline.skinnum;
|
||||
VectorCopy (ent_colormod[baseline.colormod], ent->renderer.colormod);
|
||||
ent->renderer.colormod[3] = ENTALPHA_DECODE (baseline.alpha);
|
||||
|
||||
CL_TransformEntity (ent, baseline.scale / 16.0, baseline.angles,
|
||||
baseline.origin);
|
||||
|
||||
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
|
||||
}
|
||||
|
||||
static void
|
||||
CL_ParseStaticSound (int version)
|
||||
{
|
||||
|
@ -850,8 +719,8 @@ CL_ParseServerMessage (void)
|
|||
|
||||
cl.last_servermessage = realtime;
|
||||
TEntContext_t tentCtx = {
|
||||
Transform_GetWorldPosition (cl_entities[cl.viewentity].transform),
|
||||
cl.worldmodel, cl.viewentity
|
||||
cl.viewstate.player_origin,
|
||||
cl.viewentity
|
||||
};
|
||||
|
||||
// if recording demos, copy the message out
|
||||
|
@ -921,7 +790,6 @@ CL_ParseServerMessage (void)
|
|||
|
||||
case svc_setview:
|
||||
cl.viewentity = MSG_ReadShort (net_message);
|
||||
cl.viewstate.player_entity = &cl_entities[cl.viewentity];
|
||||
break;
|
||||
|
||||
case svc_sound:
|
||||
|
@ -1035,7 +903,7 @@ CL_ParseServerMessage (void)
|
|||
Host_Error ("CL_ParseServerMessage: svc_updatecolors > "
|
||||
"MAX_SCOREBOARD");
|
||||
} else {
|
||||
entity_t *ent = &cl_entities[i+1];
|
||||
entity_t *ent = CL_GetEntity (i + 1);
|
||||
byte col = MSG_ReadByte (net_message);
|
||||
byte top = col >> 4;
|
||||
byte bot = col & 0xf;
|
||||
|
@ -1061,7 +929,7 @@ CL_ParseServerMessage (void)
|
|||
break;
|
||||
|
||||
case svc_spawnstatic:
|
||||
CL_ParseStatic (1);
|
||||
CL_ParseStatic (net_message, 1);
|
||||
break;
|
||||
|
||||
// svc_spawnbinary
|
||||
|
@ -1069,7 +937,7 @@ CL_ParseServerMessage (void)
|
|||
case svc_spawnbaseline:
|
||||
i = MSG_ReadShort (net_message);
|
||||
// must use CL_EntityNum () to force cl.num_entities up
|
||||
CL_ParseBaseline (CL_EntityNum (i), 1);
|
||||
CL_ParseBaseline (net_message, CL_EntityNum (i), 1);
|
||||
break;
|
||||
|
||||
case svc_temp_entity:
|
||||
|
@ -1205,10 +1073,10 @@ CL_ParseServerMessage (void)
|
|||
case svc_spawnbaseline2:
|
||||
i = MSG_ReadShort (net_message);
|
||||
// must use CL_EntityNum() to force cl.num_entities up
|
||||
CL_ParseBaseline (CL_EntityNum(i), 2);
|
||||
CL_ParseBaseline (net_message, CL_EntityNum(i), 2);
|
||||
break;
|
||||
case svc_spawnstatic2:
|
||||
CL_ParseStatic (2);
|
||||
CL_ParseStatic (net_message, 2);
|
||||
break;
|
||||
case svc_spawnstaticsound2:
|
||||
CL_ParseStaticSound (2);
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
|
||||
#include "sbar.h"
|
||||
|
||||
#include "client/world.h"
|
||||
|
||||
#include "nq/include/client.h"
|
||||
|
||||
static view_t *net_view;
|
||||
|
@ -75,11 +77,11 @@ SCR_CShift (void)
|
|||
mleaf_t *leaf;
|
||||
int contents = CONTENTS_EMPTY;
|
||||
|
||||
if (cls.state == ca_active && cl.worldmodel) {
|
||||
if (cls.state == ca_active && cl_world.worldmodel) {
|
||||
vec4f_t origin;
|
||||
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
|
||||
//FIXME
|
||||
leaf = Mod_PointInLeaf (&origin[0], cl.worldmodel);
|
||||
leaf = Mod_PointInLeaf (&origin[0], cl_world.worldmodel);
|
||||
contents = leaf->contents;
|
||||
}
|
||||
V_SetContentsColor (&cl.viewstate, contents);
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "compat.h"
|
||||
|
||||
#include "client/chase.h"
|
||||
#include "client/world.h"
|
||||
|
||||
#include "nq/include/host.h"
|
||||
#include "nq/include/server.h"
|
||||
|
@ -612,7 +613,7 @@ Host_ClientFrame (void)
|
|||
vec4f_t origin;
|
||||
|
||||
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
|
||||
l = Mod_PointInLeaf (&origin[0], cl.worldmodel);//FIXME
|
||||
l = Mod_PointInLeaf (&origin[0], cl_world.worldmodel);//FIXME
|
||||
if (l)
|
||||
asl = l->ambient_sound_level;
|
||||
S_Update (cl.viewstate.camera_transform, asl);
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
#include "QF/sys.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "client/world.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "world.h"
|
||||
|
||||
|
@ -1320,7 +1322,7 @@ Host_Viewmodel_f (void)
|
|||
}
|
||||
|
||||
SVfloat (e, frame) = 0;
|
||||
cl.model_precache[(int) SVfloat (e, modelindex)] = m;
|
||||
cl_world.models.a[(int) SVfloat (e, modelindex)] = m;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1333,7 +1335,7 @@ Host_Viewframe_f (void)
|
|||
e = FindViewthing ();
|
||||
if (!e)
|
||||
return;
|
||||
m = cl.model_precache[(int) SVfloat (e, modelindex)];
|
||||
m = cl_world.models.a[(int) SVfloat (e, modelindex)];
|
||||
|
||||
f = atoi (Cmd_Argv (1));
|
||||
if (f >= m->numframes)
|
||||
|
@ -1366,7 +1368,7 @@ Host_Viewnext_f (void)
|
|||
e = FindViewthing ();
|
||||
if (!e)
|
||||
return;
|
||||
m = cl.model_precache[(int) SVfloat (e, modelindex)];
|
||||
m = cl_world.models.a[(int) SVfloat (e, modelindex)];
|
||||
|
||||
SVfloat (e, frame) = SVfloat (e, frame) + 1;
|
||||
if (SVfloat (e, frame) >= m->numframes)
|
||||
|
@ -1385,7 +1387,7 @@ Host_Viewprev_f (void)
|
|||
if (!e)
|
||||
return;
|
||||
|
||||
m = cl.model_precache[(int) SVfloat (e, modelindex)];
|
||||
m = cl_world.models.a[(int) SVfloat (e, modelindex)];
|
||||
|
||||
SVfloat (e, frame) = SVfloat (e, frame) - 1;
|
||||
if (SVfloat (e, frame) < 0)
|
||||
|
|
|
@ -36,12 +36,16 @@
|
|||
|
||||
#include "QF/plugin/vid_render.h"
|
||||
|
||||
#include "client/world.h"
|
||||
|
||||
#include "nq/include/host.h"
|
||||
#include "nq/include/server.h"
|
||||
|
||||
client_state_t cl;
|
||||
client_static_t cls;
|
||||
|
||||
worldscene_t cl_world;
|
||||
|
||||
cvar_t *cl_name;
|
||||
cvar_t *cl_writecfg;
|
||||
cvar_t *demo_speed;
|
||||
|
|
|
@ -41,12 +41,9 @@ void CL_ParsePacketEntities (qboolean delta);
|
|||
void CL_SetSolidEntities (void);
|
||||
void CL_ParsePlayerinfo (void);
|
||||
void CL_Ents_Init (void);
|
||||
entity_t *CL_GetEntity (int num);
|
||||
|
||||
extern struct cvar_s *cl_deadbodyfilter;
|
||||
extern struct cvar_s *cl_gibfilter;
|
||||
|
||||
extern entity_t cl_player_ents[];
|
||||
extern entity_t cl_flag_ents[];
|
||||
extern entity_t cl_packet_ents[];
|
||||
|
||||
#endif
|
||||
|
|
|
@ -222,14 +222,10 @@ typedef struct client_state_s {
|
|||
char model_name[MAX_MODELS][MAX_QPATH];
|
||||
char sound_name[MAX_SOUNDS][MAX_QPATH];
|
||||
|
||||
struct model_s *model_precache[MAX_MODELS];
|
||||
struct sfx_s *sound_precache[MAX_SOUNDS];
|
||||
int nummodels;
|
||||
int numsounds;
|
||||
|
||||
struct plitem_s *edicts;
|
||||
struct plitem_s *worldspawn;
|
||||
|
||||
char levelname[40]; // for display on solo scoreboard
|
||||
int spectator;
|
||||
int playernum;
|
||||
|
@ -247,9 +243,7 @@ typedef struct client_state_s {
|
|||
int fbskins;
|
||||
|
||||
// refresh related state
|
||||
struct model_s *worldmodel; // cl_entitites[0].model
|
||||
int num_entities; // held in cl_entities array
|
||||
entity_t viewent; // the weapon model
|
||||
|
||||
int cdtrack; // cd audio
|
||||
|
||||
|
@ -288,10 +282,7 @@ extern struct cvar_s *cl_fb_players;
|
|||
|
||||
extern client_state_t cl;
|
||||
|
||||
typedef struct entitystateset_s DARRAY_TYPE (struct entity_state_s)
|
||||
entitystateset_t;
|
||||
extern entitystateset_t cl_static_entities;
|
||||
extern entity_t cl_entities[512];
|
||||
extern entity_t *cl_entities[512];
|
||||
extern byte cl_entity_valid[2][512];
|
||||
|
||||
extern qboolean nomaster;
|
||||
|
|
|
@ -56,6 +56,8 @@
|
|||
|
||||
#include "compat.h"
|
||||
|
||||
#include "client/world.h"
|
||||
|
||||
#include "qw/include/cl_cam.h"
|
||||
#include "qw/include/cl_demo.h"
|
||||
#include "qw/include/cl_ents.h"
|
||||
|
@ -633,8 +635,8 @@ demo_default_name (const char *argv1)
|
|||
time (&tim);
|
||||
strftime (timestring, 19, "%Y-%m-%d-%H-%M", localtime (&tim));
|
||||
|
||||
// the leading path-name is to be removed from cl.worldmodel->name
|
||||
mapname = QFS_SkipPath (cl.worldmodel->path);
|
||||
// the leading path-name is to be removed from cl_world.worldmodel->name
|
||||
mapname = QFS_SkipPath (cl_world.worldmodel->path);
|
||||
|
||||
// the map name is cut off after any "." because this would prevent
|
||||
// an extension being appended
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
#include "client/temp_entities.h"
|
||||
#include "client/view.h"
|
||||
#include "client/world.h"
|
||||
|
||||
#include "qw/msg_ucmd.h"
|
||||
#include "qw/pmove.h"
|
||||
|
@ -481,7 +482,7 @@ CL_ParsePlayerinfo (void)
|
|||
byte val;
|
||||
entity_t *ent;
|
||||
|
||||
ent = &cl_player_ents[num];
|
||||
ent = CL_GetEntity (num + 1);
|
||||
bits = MSG_ReadByte (net_message);
|
||||
if (bits & PF_ALPHA) {
|
||||
val = MSG_ReadByte (net_message);
|
||||
|
@ -529,7 +530,7 @@ CL_SetSolidEntities (void)
|
|||
frame_t *frame;
|
||||
packet_entities_t *pak;
|
||||
|
||||
pmove.physents[0].model = cl.worldmodel;
|
||||
pmove.physents[0].model = cl_world.worldmodel;
|
||||
VectorZero (pmove.physents[0].origin);
|
||||
VectorZero (pmove.physents[0].angles);
|
||||
pmove.physents[0].info = 0;
|
||||
|
@ -543,17 +544,17 @@ CL_SetSolidEntities (void)
|
|||
|
||||
if (!state->modelindex)
|
||||
continue;
|
||||
if (!cl.model_precache[state->modelindex])
|
||||
if (!cl_world.models.a[state->modelindex])
|
||||
continue;
|
||||
if (cl.model_precache[state->modelindex]->brush.hulls[1].firstclipnode
|
||||
|| cl.model_precache[state->modelindex]->clipbox) {
|
||||
if (cl_world.models.a[state->modelindex]->brush.hulls[1].firstclipnode
|
||||
|| cl_world.models.a[state->modelindex]->clipbox) {
|
||||
if (pmove.numphysent == MAX_PHYSENTS) {
|
||||
Sys_Printf ("WARNING: entity physent overflow, email "
|
||||
"quakeforge-devel@lists.quakeforge.net\n");
|
||||
break;
|
||||
}
|
||||
pmove.physents[pmove.numphysent].model =
|
||||
cl.model_precache[state->modelindex];
|
||||
cl_world.models.a[state->modelindex];
|
||||
VectorCopy (state->origin,
|
||||
pmove.physents[pmove.numphysent].origin);
|
||||
VectorCopy (state->angles,
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "QF/sys.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/scene.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "d_iface.h"
|
||||
|
@ -50,6 +51,7 @@
|
|||
#include "client/locs.h"
|
||||
#include "client/temp_entities.h"
|
||||
#include "client/view.h"
|
||||
#include "client/world.h"
|
||||
|
||||
#include "qw/bothdefs.h"
|
||||
#include "qw/msg_ucmd.h"
|
||||
|
@ -62,9 +64,8 @@
|
|||
#include "qw/include/cl_pred.h"
|
||||
#include "qw/include/host.h"
|
||||
|
||||
entity_t cl_player_ents[MAX_CLIENTS];
|
||||
entity_t cl_flag_ents[MAX_CLIENTS];
|
||||
entity_t cl_entities[512]; // FIXME: magic number
|
||||
entity_t *cl_flag_ents[MAX_CLIENTS];
|
||||
entity_t *cl_entities[512]; // FIXME: magic number
|
||||
byte cl_entity_valid[2][512];
|
||||
|
||||
void
|
||||
|
@ -72,15 +73,32 @@ CL_ClearEnts (void)
|
|||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++) {
|
||||
if (cl_flag_ents[i]) {
|
||||
Scene_DestroyEntity (cl_world.scene, cl_flag_ents[i]);
|
||||
cl_flag_ents[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 512; i++) {
|
||||
if (cl_entities[i]) {
|
||||
Scene_DestroyEntity (cl_world.scene, cl_entities[i]);
|
||||
cl_entities[i] = 0;
|
||||
}
|
||||
}
|
||||
i = qw_entstates.num_frames * qw_entstates.num_entities;
|
||||
memset (qw_entstates.frame[0], 0, i * sizeof (entity_state_t));
|
||||
memset (cl_entity_valid, 0, sizeof (cl_entity_valid));
|
||||
for (i = 0; i < sizeof (cl_entities) / sizeof (cl_entities[0]); i++)
|
||||
CL_Init_Entity (&cl_entities[i]);
|
||||
for (i = 0; i < sizeof (cl_flag_ents) / sizeof (cl_flag_ents[0]); i++)
|
||||
CL_Init_Entity (&cl_flag_ents[i]);
|
||||
for (i = 0; i < sizeof (cl_player_ents) / sizeof (cl_player_ents[0]); i++)
|
||||
CL_Init_Entity (&cl_player_ents[i]);
|
||||
}
|
||||
|
||||
entity_t *
|
||||
CL_GetEntity (int num)
|
||||
{
|
||||
if (!cl_entities[num]) {
|
||||
cl_entities[num] = Scene_CreateEntity (cl_world.scene);
|
||||
CL_Init_Entity (cl_entities[num]);
|
||||
}
|
||||
return cl_entities[num];
|
||||
}
|
||||
|
||||
// Hack hack hack
|
||||
|
@ -110,7 +128,7 @@ set_entity_model (entity_t *ent, int modelindex)
|
|||
{
|
||||
renderer_t *renderer = &ent->renderer;
|
||||
animation_t *animation = &ent->animation;
|
||||
renderer->model = cl.model_precache[modelindex];
|
||||
renderer->model = cl_world.models.a[modelindex];
|
||||
// automatic animation (torches, etc) can be either all together
|
||||
// or randomized
|
||||
if (renderer->model) {
|
||||
|
@ -134,10 +152,10 @@ CL_LinkPacketEntities (void)
|
|||
animation_t *animation;
|
||||
|
||||
frac = 1;
|
||||
for (i = 0; i < 512; i++) {
|
||||
for (i = MAX_CLIENTS + 1; i < 512; i++) {
|
||||
new = &qw_entstates.frame[cl.link_sequence & UPDATE_MASK][i];
|
||||
old = &qw_entstates.frame[cl.prev_sequence & UPDATE_MASK][i];
|
||||
ent = &cl_entities[i];
|
||||
ent = CL_GetEntity (i);
|
||||
renderer = &ent->renderer;
|
||||
animation = &ent->animation;
|
||||
forcelink = cl_entity_valid[0][i] != cl_entity_valid[1][i];
|
||||
|
@ -216,7 +234,7 @@ CL_LinkPacketEntities (void)
|
|||
if (ent->visibility.efrag) {
|
||||
r_funcs->R_RemoveEfrags (ent);
|
||||
}
|
||||
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
|
||||
r_funcs->R_AddEfrags (&cl_world.worldmodel->brush, ent);
|
||||
}
|
||||
} else {
|
||||
vec4f_t delta = new->origin - old->origin;
|
||||
|
@ -248,15 +266,15 @@ CL_LinkPacketEntities (void)
|
|||
= Transform_GetWorldPosition (ent->transform);
|
||||
if (!VectorCompare (org, ent->old_origin)) {//FIXME
|
||||
r_funcs->R_RemoveEfrags (ent);
|
||||
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
|
||||
r_funcs->R_AddEfrags (&cl_world.worldmodel->brush, ent);
|
||||
}
|
||||
} else {
|
||||
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
|
||||
r_funcs->R_AddEfrags (&cl_world.worldmodel->brush, ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ent->visibility.efrag) {
|
||||
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
|
||||
r_funcs->R_AddEfrags (&cl_world.worldmodel->brush, ent);
|
||||
}
|
||||
|
||||
// rotate binary objects locally
|
||||
|
@ -288,7 +306,7 @@ CL_UpdateFlagModels (entity_t *ent, int key)
|
|||
float f;
|
||||
entity_t *fent;
|
||||
|
||||
fent = &cl_flag_ents[key];
|
||||
fent = cl_flag_ents[key];
|
||||
|
||||
if (!fent->active) {
|
||||
return;
|
||||
|
@ -322,7 +340,7 @@ CL_AddFlagModels (entity_t *ent, int team, int key)
|
|||
{
|
||||
entity_t *fent;
|
||||
|
||||
fent = &cl_flag_ents[key];
|
||||
fent = cl_flag_ents[key];
|
||||
|
||||
if (cl_flagindex == -1) {
|
||||
fent->active = 0;
|
||||
|
@ -336,7 +354,7 @@ CL_AddFlagModels (entity_t *ent, int team, int key)
|
|||
}
|
||||
CL_UpdateFlagModels (ent, key);
|
||||
|
||||
fent->renderer.model = cl.model_precache[cl_flagindex];
|
||||
fent->renderer.model = cl_world.models.a[cl_flagindex];
|
||||
fent->renderer.skinnum = team;
|
||||
|
||||
return fent;
|
||||
|
@ -347,7 +365,7 @@ CL_RemoveFlagModels (int key)
|
|||
{
|
||||
entity_t *fent;
|
||||
|
||||
fent = &cl_flag_ents[key];
|
||||
fent = cl_flag_ents[key];
|
||||
fent->active = 0;
|
||||
Transform_SetParent (fent->transform, 0);
|
||||
}
|
||||
|
@ -380,7 +398,7 @@ CL_LinkPlayers (void)
|
|||
|
||||
for (j = 0, player = cl.players, state = frame->playerstate;
|
||||
j < MAX_CLIENTS; j++, player++, state++) {
|
||||
ent = &cl_player_ents[j];
|
||||
ent = CL_GetEntity (j + 1);
|
||||
if (ent->visibility.efrag)
|
||||
r_funcs->R_RemoveEfrags (ent);
|
||||
if (player->flag_ent && player->flag_ent->visibility.efrag) {
|
||||
|
@ -395,7 +413,8 @@ CL_LinkPlayers (void)
|
|||
// spawn light flashes, even ones coming from invisible objects
|
||||
if (j == cl.playernum) {
|
||||
org = cl.viewstate.player_origin;
|
||||
r_data->player_entity = &cl_player_ents[j];
|
||||
r_data->player_entity = ent;
|
||||
cl.viewstate.player_entity = ent;
|
||||
clientplayer = true;
|
||||
} else {
|
||||
org = state->pls.es.origin;
|
||||
|
@ -453,8 +472,8 @@ CL_LinkPlayers (void)
|
|||
ang[ROLL] = V_CalcRoll (ang, state->pls.es.velocity) * 4.0;
|
||||
|
||||
if (ent->renderer.model
|
||||
!= cl.model_precache[state->pls.es.modelindex]) {
|
||||
ent->renderer.model = cl.model_precache[state->pls.es.modelindex];
|
||||
!= cl_world.models.a[state->pls.es.modelindex]) {
|
||||
ent->renderer.model = cl_world.models.a[state->pls.es.modelindex];
|
||||
ent->animation.nolerp = 1;
|
||||
}
|
||||
ent->animation.frame = state->pls.es.frame;
|
||||
|
@ -492,10 +511,10 @@ CL_LinkPlayers (void)
|
|||
}
|
||||
|
||||
// stuff entity in map
|
||||
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
|
||||
r_funcs->R_AddEfrags (&cl_world.worldmodel->brush, ent);
|
||||
if (player->flag_ent) {
|
||||
CL_UpdateFlagModels (ent, j);
|
||||
r_funcs->R_AddEfrags (&cl.worldmodel->brush, player->flag_ent);
|
||||
r_funcs->R_AddEfrags (&cl_world.worldmodel->brush, player->flag_ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -516,7 +535,7 @@ CL_EmitEntities (void)
|
|||
return;
|
||||
|
||||
TEntContext_t tentCtx = {
|
||||
cl.viewstate.player_origin, cl.worldmodel, cl.viewentity
|
||||
cl.viewstate.player_origin, cl.viewentity
|
||||
};
|
||||
|
||||
CL_LinkPlayers ();
|
||||
|
@ -530,5 +549,4 @@ CL_EmitEntities (void)
|
|||
void
|
||||
CL_Ents_Init (void)
|
||||
{
|
||||
r_data->view_model = &cl.viewent;
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
|
||||
#include "QF/plugin/console.h"
|
||||
#include "QF/scene/transform.h"
|
||||
#include "QF/scene/scene.h"
|
||||
|
||||
#include "buildnum.h"
|
||||
#include "compat.h"
|
||||
|
@ -99,6 +100,7 @@
|
|||
#include "client/particles.h"
|
||||
#include "client/temp_entities.h"
|
||||
#include "client/view.h"
|
||||
#include "client/world.h"
|
||||
|
||||
#include "qw/bothdefs.h"
|
||||
#include "qw/pmove.h"
|
||||
|
@ -229,7 +231,7 @@ CL_Quit_f (void)
|
|||
static void
|
||||
pointfile_f (void)
|
||||
{
|
||||
CL_LoadPointFile (cl.worldmodel);
|
||||
CL_LoadPointFile (cl_world.worldmodel);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -385,6 +387,9 @@ CL_ClearState (void)
|
|||
|
||||
S_StopAllSounds ();
|
||||
|
||||
if (cl.viewstate.weapon_entity) {
|
||||
Scene_DestroyEntity (cl_world.scene, cl.viewstate.weapon_entity);
|
||||
}
|
||||
// wipe the entire cl structure
|
||||
if (cl.serverinfo)
|
||||
Info_Destroy (cl.serverinfo);
|
||||
|
@ -402,7 +407,6 @@ CL_ClearState (void)
|
|||
cl.chasestate.viewstate = &cl.viewstate;
|
||||
cl.viewstate.punchangle = (vec4f_t) {0, 0, 0, 1};
|
||||
|
||||
|
||||
// Note: we should probably hack around this and give diff values for
|
||||
// diff gamedirs
|
||||
cl.fpd = FPD_DEFAULT;
|
||||
|
@ -412,9 +416,6 @@ CL_ClearState (void)
|
|||
cl.frames[i].packet_entities.entities = qw_entstates.frame[i];
|
||||
cl.serverinfo = Info_ParseString ("", MAX_INFO_STRING, 0);
|
||||
|
||||
CL_Init_Entity (&cl.viewent);
|
||||
cl.viewstate.weapon_entity = &cl.viewent;
|
||||
|
||||
Sys_MaskPrintf (SYS_dev, "Clearing memory\n");
|
||||
VID_ClearMemory ();
|
||||
Mod_ClearAll ();
|
||||
|
@ -424,6 +425,10 @@ CL_ClearState (void)
|
|||
CL_ClearEnts ();
|
||||
CL_ClearTEnts ();
|
||||
|
||||
cl.viewstate.weapon_entity = Scene_CreateEntity (cl_world.scene);
|
||||
CL_Init_Entity (cl.viewstate.weapon_entity);
|
||||
r_data->view_model = cl.viewstate.weapon_entity;
|
||||
|
||||
r_funcs->R_ClearState ();
|
||||
|
||||
SZ_Clear (&cls.netchan.message);
|
||||
|
@ -519,7 +524,7 @@ CL_Disconnect (void)
|
|||
Info_Destroy (cl.players[i].userinfo);
|
||||
memset (&cl.players[i], 0, sizeof (cl.players[i]));
|
||||
}
|
||||
cl.worldmodel = NULL;
|
||||
cl_world.worldmodel = NULL;
|
||||
cl.validsequence = 0;
|
||||
}
|
||||
|
||||
|
@ -1216,6 +1221,7 @@ CL_Init (void)
|
|||
CL_Ents_Init ();
|
||||
CL_Particles_Init ();
|
||||
CL_TEnts_Init ();
|
||||
CL_World_Init ();
|
||||
CL_ClearState ();
|
||||
Pmove_Init ();
|
||||
|
||||
|
@ -1725,7 +1731,7 @@ Host_Frame (float time)
|
|||
vec4f_t origin;
|
||||
|
||||
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
|
||||
l = Mod_PointInLeaf (&origin[0], cl.worldmodel);//FIXME
|
||||
l = Mod_PointInLeaf (&origin[0], cl_world.worldmodel);//FIXME
|
||||
if (l)
|
||||
asl = l->ambient_sound_level;
|
||||
S_Update (cl.viewstate.camera_transform, asl);
|
||||
|
|
|
@ -61,12 +61,15 @@
|
|||
#include "QF/teamplay.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "QF/scene/scene.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "sbar.h"
|
||||
|
||||
#include "client/effects.h"
|
||||
#include "client/temp_entities.h"
|
||||
#include "client/view.h"
|
||||
#include "client/world.h"
|
||||
|
||||
#include "qw/bothdefs.h"
|
||||
#include "qw/pmove.h"
|
||||
|
@ -170,40 +173,6 @@ int packet_latency[NET_TIMINGS];
|
|||
|
||||
extern cvar_t *hud_scoreboard_uid;
|
||||
|
||||
entitystateset_t cl_static_entities = DARRAY_STATIC_INIT (32);
|
||||
|
||||
static void
|
||||
CL_LoadSky (void)
|
||||
{
|
||||
plitem_t *item;
|
||||
const char *name = 0;
|
||||
static const char *sky_keys[] = {
|
||||
"sky", // Q2/DarkPlaces
|
||||
"skyname", // old QF
|
||||
"qlsky", // QuakeLives
|
||||
0
|
||||
};
|
||||
|
||||
// R_LoadSkys does the right thing with null pointers.
|
||||
if (cl.serverinfo) {
|
||||
name = Info_ValueForKey (cl.serverinfo, "sky");
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
if (!cl.worldspawn) {
|
||||
r_funcs->R_LoadSkys (0);
|
||||
return;
|
||||
}
|
||||
for (const char **key = sky_keys; *key; key++) {
|
||||
if ((item = PL_ObjectForKey (cl.worldspawn, *key))) {
|
||||
name = PL_String (item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
r_funcs->R_LoadSkys (name);
|
||||
}
|
||||
|
||||
int
|
||||
CL_CalcNet (void)
|
||||
{
|
||||
|
@ -290,49 +259,20 @@ CL_CheckOrDownloadFile (const char *filename)
|
|||
return false;
|
||||
}
|
||||
|
||||
static plitem_t *
|
||||
map_ent (const char *mapname)
|
||||
{
|
||||
static progs_t edpr;
|
||||
char *name = malloc (strlen (mapname) + 4 + 1);
|
||||
char *buf;
|
||||
plitem_t *edicts = 0;
|
||||
QFile *ent_file;
|
||||
|
||||
QFS_StripExtension (mapname, name);
|
||||
strcat (name, ".ent");
|
||||
ent_file = QFS_VOpenFile (name, 0, cl.model_precache[1]->vpath);
|
||||
if ((buf = (char *) QFS_LoadFile (ent_file, 0))) {
|
||||
edicts = ED_Parse (&edpr, buf);
|
||||
free (buf);
|
||||
} else {
|
||||
edicts = ED_Parse (&edpr, cl.model_precache[1]->brush.entities);
|
||||
}
|
||||
free (name);
|
||||
return edicts;
|
||||
}
|
||||
|
||||
static void
|
||||
CL_NewMap (const char *mapname)
|
||||
{
|
||||
cl_static_entities.size = 0;
|
||||
r_funcs->R_NewMap (cl.worldmodel, cl.model_precache, cl.nummodels);
|
||||
Team_NewMap ();
|
||||
Con_NewMap ();
|
||||
Hunk_Check (0); // make sure nothing is hurt
|
||||
Sbar_CenterPrint (0);
|
||||
|
||||
if (cl.model_precache[1] && cl.model_precache[1]->brush.entities) {
|
||||
cl.edicts = map_ent (mapname);
|
||||
if (cl.edicts) {
|
||||
cl.worldspawn = PL_ObjectAtIndex (cl.edicts, 0);
|
||||
CL_LoadSky ();
|
||||
if (r_funcs->Fog_ParseWorldspawn)
|
||||
r_funcs->Fog_ParseWorldspawn (cl.worldspawn);
|
||||
}
|
||||
const char *skyname = 0;
|
||||
// R_LoadSkys does the right thing with null pointers.
|
||||
if (cl.serverinfo) {
|
||||
skyname = Info_ValueForKey (cl.serverinfo, "sky");
|
||||
}
|
||||
|
||||
map_cfg (mapname, 1);
|
||||
CL_World_NewMap (mapname, skyname);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -357,7 +297,7 @@ Model_NextDownload (void)
|
|||
}
|
||||
|
||||
if (cl.model_name[1])
|
||||
map_cfg (cl.model_name[1], 0);
|
||||
CL_MapCfg (cl.model_name[1]);
|
||||
|
||||
for (i = 1; i < cl.nummodels; i++) {
|
||||
const char *info_key = 0;
|
||||
|
@ -365,9 +305,10 @@ Model_NextDownload (void)
|
|||
if (!cl.model_name[i][0])
|
||||
break;
|
||||
|
||||
cl.model_precache[i] = Mod_ForName (cl.model_name[i], false);
|
||||
DARRAY_APPEND (&cl_world.models,
|
||||
Mod_ForName (cl.model_name[i], false));
|
||||
|
||||
if (!cl.model_precache[i]) {
|
||||
if (!cl_world.models.a[i]) {
|
||||
Sys_Printf ("\nThe required model file '%s' could not be found or "
|
||||
"downloaded.\n\n", cl.model_name[i]);
|
||||
Sys_Printf ("You may need to download or purchase a %s client "
|
||||
|
@ -378,18 +319,18 @@ Model_NextDownload (void)
|
|||
}
|
||||
|
||||
if (strequal (cl.model_name[i], "progs/player.mdl")
|
||||
&& cl.model_precache[i]->type == mod_alias) {
|
||||
&& cl_world.models.a[i]->type == mod_alias) {
|
||||
info_key = pmodel_name;
|
||||
//XXX mod_funcs->Skin_Player_Model (cl.model_precache[i]);
|
||||
//XXX mod_funcs->Skin_Player_Model (cl_world.models.a[i]);
|
||||
}
|
||||
if (strequal (cl.model_name[i], "progs/eyes.mdl")
|
||||
&& cl.model_precache[i]->type == mod_alias)
|
||||
&& cl_world.models.a[i]->type == mod_alias)
|
||||
info_key = emodel_name;
|
||||
|
||||
if (info_key && cl_model_crcs->int_val) {
|
||||
aliashdr_t *ahdr = cl.model_precache[i]->aliashdr;
|
||||
aliashdr_t *ahdr = cl_world.models.a[i]->aliashdr;
|
||||
if (!ahdr)
|
||||
ahdr = Cache_Get (&cl.model_precache[i]->cache);
|
||||
ahdr = Cache_Get (&cl_world.models.a[i]->cache);
|
||||
Info_SetValueForKey (cls.userinfo, info_key, va (0, "%d",
|
||||
ahdr->crc),
|
||||
0);
|
||||
|
@ -398,14 +339,14 @@ Model_NextDownload (void)
|
|||
SZ_Print (&cls.netchan.message, va (0, "setinfo %s %d",
|
||||
info_key, ahdr->crc));
|
||||
}
|
||||
if (!cl.model_precache[i]->aliashdr)
|
||||
Cache_Release (&cl.model_precache[i]->cache);
|
||||
if (!cl_world.models.a[i]->aliashdr)
|
||||
Cache_Release (&cl_world.models.a[i]->cache);
|
||||
}
|
||||
}
|
||||
|
||||
// Something went wrong (probably in the server, probably a TF server)
|
||||
// We need to disconnect gracefully.
|
||||
if (!cl.model_precache[1]) {
|
||||
if (!cl_world.models.a[1]) {
|
||||
Sys_Printf ("\nThe server has failed to provide the map name.\n\n");
|
||||
Sys_Printf ("Disconnecting to prevent a crash.\n\n");
|
||||
CL_Disconnect ();
|
||||
|
@ -413,8 +354,8 @@ Model_NextDownload (void)
|
|||
}
|
||||
|
||||
// all done
|
||||
cl.worldmodel = cl.model_precache[1];
|
||||
cl.chasestate.worldmodel = cl.worldmodel;
|
||||
cl_world.worldmodel = cl_world.models.a[1];
|
||||
cl.chasestate.worldmodel = cl_world.worldmodel;
|
||||
CL_NewMap (cl.model_name[1]);
|
||||
|
||||
// done with modellist, request first of static signon messages
|
||||
|
@ -422,7 +363,7 @@ Model_NextDownload (void)
|
|||
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
|
||||
MSG_WriteString (&cls.netchan.message,
|
||||
va (0, prespawn_name, cl.servercount,
|
||||
cl.worldmodel->brush.checksum2));
|
||||
cl_world.worldmodel->brush.checksum2));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -453,7 +394,8 @@ Sound_NextDownload (void)
|
|||
}
|
||||
|
||||
// done with sounds, request models now
|
||||
memset (cl.model_precache, 0, sizeof (cl.model_precache));
|
||||
cl_world.models.size = 0;
|
||||
DARRAY_APPEND (&cl_world.models, 0);// ind 0 is null model
|
||||
cl_playerindex = -1;
|
||||
cl_flagindex = -1;
|
||||
cl_h_playerindex = -1;
|
||||
|
@ -832,7 +774,6 @@ CL_ParseServerData (void)
|
|||
}
|
||||
|
||||
cl.viewentity = cl.playernum + 1;
|
||||
cl.viewstate.player_entity = &cl_entities[cl.viewentity];
|
||||
cl.viewstate.bob_enabled = !cl.spectator;
|
||||
|
||||
// get the full level name
|
||||
|
@ -957,54 +898,6 @@ CL_ParseModellist (void)
|
|||
Model_NextDownload ();
|
||||
}
|
||||
|
||||
static void
|
||||
CL_ParseBaseline (entity_state_t *es)
|
||||
{
|
||||
es->modelindex = MSG_ReadByte (net_message);
|
||||
es->frame = MSG_ReadByte (net_message);
|
||||
es->colormap = MSG_ReadByte (net_message);
|
||||
es->skinnum = MSG_ReadByte (net_message);
|
||||
|
||||
MSG_ReadCoordAngleV (net_message, &es->origin[0], es->angles);//FIXME
|
||||
es->origin[3] = 1;
|
||||
|
||||
// LordHavoc: set up baseline to for new effects (alpha, colormod, etc)
|
||||
es->colormod = 255;
|
||||
es->alpha = 255;
|
||||
es->scale = 16;
|
||||
es->glow_size = 0;
|
||||
es->glow_color = 254;
|
||||
}
|
||||
|
||||
/*
|
||||
CL_ParseStatic
|
||||
|
||||
Static entities are non-interactive world objects
|
||||
like torches
|
||||
*/
|
||||
static void
|
||||
CL_ParseStatic (void)
|
||||
{
|
||||
entity_t *ent;
|
||||
entity_state_t es;
|
||||
|
||||
CL_ParseBaseline (&es);
|
||||
|
||||
ent = r_funcs->R_AllocEntity ();
|
||||
CL_Init_Entity (ent);
|
||||
|
||||
DARRAY_APPEND (&cl_static_entities, es);
|
||||
|
||||
// copy it to the current state
|
||||
ent->renderer.model = cl.model_precache[es.modelindex];
|
||||
ent->animation.frame = es.frame;
|
||||
ent->renderer.skinnum = es.skinnum;
|
||||
|
||||
CL_TransformEntity (ent, es.scale / 16.0, es.angles, es.origin);
|
||||
|
||||
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
|
||||
}
|
||||
|
||||
static void
|
||||
CL_ParseStaticSound (void)
|
||||
{
|
||||
|
@ -1275,7 +1168,7 @@ CL_SetStat (int stat, int value)
|
|||
break;
|
||||
}
|
||||
cl.stats[stat] = value;
|
||||
cl.viewstate.weapon_model = cl.model_precache[cl.stats[STAT_WEAPON]];
|
||||
cl.viewstate.weapon_model = cl_world.models.a[cl.stats[STAT_WEAPON]];
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1318,7 +1211,7 @@ CL_ParseServerMessage (void)
|
|||
const char *str;
|
||||
static dstring_t *stuffbuf;
|
||||
TEntContext_t tentCtx = {
|
||||
cl.viewstate.player_origin, cl.worldmodel, cl.viewentity
|
||||
cl.viewstate.player_origin, cl.viewentity
|
||||
};
|
||||
|
||||
received_framecount = host_framecount;
|
||||
|
@ -1513,14 +1406,14 @@ CL_ParseServerMessage (void)
|
|||
break;
|
||||
|
||||
case svc_spawnstatic:
|
||||
CL_ParseStatic ();
|
||||
CL_ParseStatic (net_message, 1);
|
||||
break;
|
||||
|
||||
// svc_spawnbinary
|
||||
|
||||
case svc_spawnbaseline:
|
||||
i = MSG_ReadShort (net_message);
|
||||
CL_ParseBaseline (&qw_entstates.baseline[i]);
|
||||
CL_ParseBaseline (net_message, &qw_entstates.baseline[i], 1);
|
||||
break;
|
||||
|
||||
case svc_temp_entity:
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
|
||||
#include "client/hud.h"
|
||||
#include "client/view.h"
|
||||
#include "client/world.h"
|
||||
|
||||
#include "qw/include/client.h"
|
||||
#include "qw/include/cl_parse.h"
|
||||
|
@ -77,11 +78,11 @@ SCR_CShift (void)
|
|||
mleaf_t *leaf;
|
||||
int contents = CONTENTS_EMPTY;
|
||||
|
||||
if (cls.state == ca_active && cl.worldmodel) {
|
||||
if (cls.state == ca_active && cl_world.worldmodel) {
|
||||
vec4f_t origin;
|
||||
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
|
||||
//FIXME
|
||||
leaf = Mod_PointInLeaf (&origin[0], cl.worldmodel);
|
||||
leaf = Mod_PointInLeaf (&origin[0], cl_world.worldmodel);
|
||||
contents = leaf->contents;
|
||||
}
|
||||
V_SetContentsColor (&cl.viewstate, contents);
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "compat.h"
|
||||
|
||||
#include "client/hud.h"
|
||||
#include "client/world.h"
|
||||
|
||||
#include "qw/bothdefs.h"
|
||||
#include "qw/include/cl_cam.h"
|
||||
|
@ -1109,8 +1110,8 @@ Sbar_LogFrags (void)
|
|||
if (t)
|
||||
Qwrite (file, t, strlen (t));
|
||||
|
||||
Qprintf (file, "%s\n%s %s\n", cls.servername->str, cl.worldmodel->path,
|
||||
cl.levelname);
|
||||
Qprintf (file, "%s\n%s %s\n", cls.servername->str,
|
||||
cl_world.worldmodel->path, cl.levelname);
|
||||
|
||||
// scores
|
||||
Sbar_SortFrags (true);
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "compat.h"
|
||||
|
||||
#include "client/locs.h"
|
||||
#include "client/world.h"
|
||||
|
||||
#include "qw/bothdefs.h"
|
||||
#include "qw/include/cl_input.h"
|
||||
|
@ -289,8 +290,8 @@ Team_NewMap (void)
|
|||
|
||||
died = false;
|
||||
recorded_location = false;
|
||||
mapname = strdup (cl.worldmodel->path);
|
||||
t2 = malloc (sizeof (cl.worldmodel->path));
|
||||
mapname = strdup (cl_world.worldmodel->path);
|
||||
t2 = malloc (sizeof (cl_world.worldmodel->path));
|
||||
if (!mapname || !t2)
|
||||
Sys_Error ("Can't duplicate mapname!");
|
||||
map_to_loc (mapname,t2);
|
||||
|
@ -340,16 +341,16 @@ locs_loc (void)
|
|||
"parameter\n");
|
||||
return;
|
||||
}
|
||||
if (!cl.worldmodel) {
|
||||
if (!cl_world.worldmodel) {
|
||||
Sys_Printf ("No map loaded. Unable to work with location markers.\n");
|
||||
return;
|
||||
}
|
||||
if (Cmd_Argc () >= 3)
|
||||
desc = Cmd_Args (2);
|
||||
mapname = malloc (sizeof (cl.worldmodel->path));
|
||||
mapname = malloc (sizeof (cl_world.worldmodel->path));
|
||||
if (!mapname)
|
||||
Sys_Error ("Can't duplicate mapname!");
|
||||
map_to_loc (cl.worldmodel->path, mapname);
|
||||
map_to_loc (cl_world.worldmodel->path, mapname);
|
||||
snprintf (locfile, sizeof (locfile), "%s/%s",
|
||||
qfs_gamedir->dir.def, mapname);
|
||||
free (mapname);
|
||||
|
|
Loading…
Reference in a new issue