[renderer] Pass in a camera transform

More r_data cleanup. Things could be better still, but this is a start.
This commit is contained in:
Bill Currie 2022-02-28 16:59:38 +09:00
parent ca9e8a3b68
commit 57dd4494cc
22 changed files with 134 additions and 84 deletions

View file

@ -31,6 +31,7 @@
#include <QF/qtypes.h>
struct sfx_s;
struct transform_s;
typedef struct snd_render_funcs_s {
void (*init) (void);
@ -47,8 +48,7 @@ typedef struct snd_render_funcs_s {
struct sfx_s *(*precache_sound) (const char *sample);
struct sfx_s *(*load_sound) (const char *name);
void (*update) (const vec3_t origin, const vec3_t v_forward,
const vec3_t v_right, const vec3_t v_up,
void (*update) (struct transform_s *ear,
const byte *ambient_sound_levels);
void (*stop_all_sounds) (void);
void (*extra_update) (void);

View file

@ -31,12 +31,15 @@
#include "QF/qtypes.h"
struct transform_s;
void SCR_Init_Cvars (void);
void SCR_Init (void);
typedef void (*SCR_Func)(void);
// scr_funcs is a null terminated array
void SCR_UpdateScreen (double realtime, SCR_Func *scr_funcs);
void SCR_UpdateScreen (struct transform_s *camera, double realtime,
SCR_Func *scr_funcs);
void SCR_SizeUp (void);
void SCR_SizeDown (void);

View file

@ -34,6 +34,8 @@
#include "QF/mathlib.h"
struct transform_s;
/**
\ingroup sound
*/
@ -129,16 +131,15 @@ void S_StopAllSounds(void);
/** Update the sound engine with the client's position and orientation and
render some sound.
\param origin 3d coords of the client
\param ear Transform for the position and orientation of the stereo
sound pickup.
\param v_forward 3d vector of the client's facing direction
\param v_right 3d vector of the client's rightward direction
\param v_up 3d vector of the client's upward direction
\param ambient_sound_level NUM_AMBIENTS bytes indicating current ambient
sound levels
*/
void S_Update (const vec3_t origin, const vec3_t v_forward,
const vec3_t v_right, const vec3_t v_up,
const byte *ambient_sound_level);
void S_Update (struct transform_s *ear, const byte *ambient_sound_level);
/** Render some more sound without updating the client's position/orientation.
*/

View file

@ -103,6 +103,8 @@ typedef struct TEntContext_s {
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);

View file

@ -45,6 +45,7 @@ typedef struct viewstate_s {
vec4f_t punchangle;
vec3_t angles;
float frametime;
struct transform_s *camera_transform;
double time;
float height;
int weaponframe;

View file

@ -44,6 +44,7 @@
#include "QF/sound.h"
#include "QF/zone.h"
struct transform_s;
typedef struct portable_samplepair_s portable_samplepair_t;
typedef struct snd_s snd_t;
typedef struct wavinfo_s wavinfo_t;
@ -363,8 +364,7 @@ void SND_AmbientOn (snd_t *snd);
\param ambient_sound_level Pointer to 4 bytes indicating the levels at
which to play the ambient sounds.
*/
void SND_SetListener (snd_t *snd, const vec3_t origin, const vec3_t v_forward,
const vec3_t v_right, const vec3_t v_up,
void SND_SetListener (snd_t *snd, struct transform_s *ear,
const byte *ambient_sound_level);
/** Stop all sounds from playing.

View file

@ -47,6 +47,8 @@
#include "QF/quakefs.h"
#include "QF/sys.h"
#include "QF/scene/transform.h"
#include "snd_internal.h"
static channel_t *free_channels;
@ -64,10 +66,10 @@ static sfx_t *ambient_sfx[NUM_AMBIENTS];
static vec_t sound_nominal_clip_dist = 1000.0;
static vec3_t listener_origin;
static vec3_t listener_forward;
static vec3_t listener_right;
static vec3_t listener_up;
static vec4f_t listener_origin;
static vec4f_t listener_forward;
static vec4f_t listener_right;
static vec4f_t listener_up;
static cvar_t *snd_phasesep;
static cvar_t *snd_volumesep;
@ -245,7 +247,8 @@ s_play_f (void *_snd)
dsprintf (name, "%s", Cmd_Argv (i));
}
sfx = SND_PrecacheSound (snd, name->str);
SND_StartSound (snd, hash++, 0, sfx, listener_origin, 1.0, 1.0);
//FIXME
SND_StartSound (snd, hash++, 0, sfx, &listener_origin[0], 1.0, 1.0);
i++;
}
dstring_delete (name);
@ -270,7 +273,8 @@ s_playcenter_f (void *_snd)
dsprintf (name, "%s", Cmd_Argv (i));
}
sfx = SND_PrecacheSound (snd, name->str);
SND_StartSound (snd, viewent, 0, sfx, listener_origin, 1.0, 1.0);
//FIXME
SND_StartSound (snd, viewent, 0, sfx, &listener_origin[0], 1.0, 1.0);
}
dstring_delete (name);
}
@ -294,7 +298,8 @@ s_playvol_f (void *_snd)
}
sfx = SND_PrecacheSound (snd, name->str);
vol = atof (Cmd_Argv (i + 1));
SND_StartSound (snd, hash++, 0, sfx, listener_origin, vol, 1.0);
//FIXME
SND_StartSound (snd, hash++, 0, sfx, &listener_origin[0], vol, 1.0);
i += 2;
}
dstring_delete (name);
@ -539,17 +544,22 @@ s_combine_channel (channel_t *combine, channel_t *ch)
}
void
SND_SetListener (snd_t *snd, const vec3_t origin, const vec3_t forward,
const vec3_t right, const vec3_t up,
const byte *ambient_sound_level)
SND_SetListener (snd_t *snd, transform_t *ear, const byte *ambient_sound_level)
{
int i, j;
channel_t *combine, *ch;
VectorCopy (origin, listener_origin);
VectorCopy (forward, listener_forward);
VectorCopy (right, listener_right);
VectorCopy (up, listener_up);
if (ear) {
listener_origin = Transform_GetWorldPosition (ear);
listener_forward = Transform_Forward (ear);
listener_right = Transform_Right (ear);
listener_up = Transform_Up (ear);
} else {
listener_origin = (vec4f_t) { };
listener_forward = (vec4f_t) {1, 0, 0, 0};
listener_right = (vec4f_t) {0, -1, 0, 0};
listener_up = (vec4f_t) {0, 0, 1, 0};
}
// update general area ambient sound sources
s_updateAmbientSounds (snd, ambient_sound_level);

View file

@ -211,8 +211,7 @@ s_update_ (void)
Called once each time through the main loop
*/
static void
s_update (const vec3_t origin, const vec3_t forward, const vec3_t right,
const vec3_t up, const byte *ambient_sound_level)
s_update (struct transform_s *ear, const byte *ambient_sound_level)
{
if (!sound_started || (snd_blocked > 0))
return;
@ -221,7 +220,7 @@ s_update (const vec3_t origin, const vec3_t forward, const vec3_t right,
snd_output_funcs->on_update (&snd);
}
SND_SetListener (&snd, origin, forward, right, up, ambient_sound_level);
SND_SetListener (&snd, ear, ambient_sound_level);
if (snd_output_data->model == som_push) {
// mix some sound

View file

@ -166,12 +166,10 @@ S_PrecacheSound (const char *sample)
}
VISIBLE void
S_Update (const vec3_t origin, const vec3_t v_forward, const vec3_t v_right,
const vec3_t v_up, const byte *ambient_sound_level)
S_Update (struct transform_s *ear, const byte *ambient_sound_level)
{
if (snd_render_funcs)
snd_render_funcs->update (origin, v_forward, v_right, v_up,
ambient_sound_level);
snd_render_funcs->update (ear, ambient_sound_level);
}
VISIBLE void

View file

@ -4,6 +4,7 @@ EXTRA_PROGRAMS += libs/audio/test/testsound
testaudio_libs= \
libs/audio/libQFsound.la \
libs/scene/libQFscene.la \
libs/ruamoko/libQFruamoko.la \
libs/util/libQFutil.la

View file

@ -88,7 +88,7 @@ main (int argc, const char *argv[])
while (1) {
Cbuf_Execute_Stack (testsound_cbuf);
S_Update (vec3_origin, vec3_origin, vec3_origin, vec3_origin, 0);
S_Update (0, 0);
usleep(20 * 1000);
}
Sys_Quit ();

View file

@ -86,7 +86,7 @@ typedef struct tent_obj_s {
static PR_RESMAP (tent_t) temp_entities;
static PR_RESMAP (tent_obj_t) tent_objects;
static scene_t *scene;
scene_t *cl_scene;
static tent_obj_t *cl_beams;
static tent_obj_t *cl_explosions;
@ -137,7 +137,7 @@ CL_TEnts_Precache (int phase)
void
CL_TEnts_Init (void)
{
scene = Scene_NewScene ();
cl_scene = Scene_NewScene ();
QFS_GamedirCallback (CL_TEnts_Precache);
CL_TEnts_Precache (1);
@ -155,7 +155,7 @@ CL_Init_Entity (entity_t *ent)
}
memset (ent, 0, sizeof (*ent));
ent->transform = Transform_New (scene, 0);
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;

View file

@ -43,6 +43,7 @@
#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"
/*
@ -475,7 +476,7 @@ V_PrepBlend (viewstate_t *vs)
static void
CalcGunAngle (viewstate_t *vs)
{
vec4f_t rotation = r_data->refdef->viewrotation;
vec4f_t rotation = Transform_GetWorldRotation (vs->camera_transform);
//FIXME make child of camera
Transform_SetWorldRotation (vs->weapon_entity->transform, rotation);
}
@ -483,7 +484,8 @@ CalcGunAngle (viewstate_t *vs)
static void
V_BoundOffsets (viewstate_t *vs)
{
vec4f_t offset = r_data->refdef->viewposition - vs->origin;
vec4f_t offset = Transform_GetWorldPosition (vs->camera_transform);
offset -= vs->origin;
// absolutely bound refresh reletive to entity clipping hull
// so the view can never be inside a solid wall
@ -491,7 +493,7 @@ V_BoundOffsets (viewstate_t *vs)
offset[0] = bound (-14, offset[0], 14);
offset[1] = bound (-14, offset[1], 14);
offset[2] = bound (-22, offset[2], 30);
r_data->refdef->viewposition = vs->origin + offset;
Transform_SetWorldPosition (vs->camera_transform, vs->origin + offset);
}
static vec4f_t
@ -525,7 +527,8 @@ V_AddIdle (viewstate_t *vs)
vec4f_t rot = normalf (qmulf (yaw, qmulf (pitch, roll)));
// rotate the view
r_data->refdef->viewrotation = qmulf (rot, r_data->refdef->viewrotation);
vec4f_t rotation = Transform_GetWorldRotation (vs->camera_transform);
Transform_SetWorldRotation (vs->camera_transform, qmulf (rot, rotation));
// counter-rotate the weapon
rot = qmulf (qconjf (rot),
@ -559,7 +562,8 @@ V_CalcViewRoll (viewstate_t *vs)
vec4f_t rot;
AngleQuat (ang, &rot[0]);//FIXME
r_data->refdef->viewrotation = qmulf (r_data->refdef->viewrotation, rot);
vec4f_t rotation = Transform_GetWorldRotation (vs->camera_transform);
Transform_SetWorldRotation (vs->camera_transform, qmulf (rotation, rot));
}
static void
@ -575,8 +579,8 @@ V_CalcIntermissionRefdef (viewstate_t *vs)
// view is the weapon model (visible only from inside body)
view = vs->weapon_entity;
r_data->refdef->viewposition = origin;
r_data->refdef->viewrotation = rotation;
Transform_SetWorldPosition (vs->camera_transform, origin);
Transform_SetWorldRotation (vs->camera_transform, rotation);
view->renderer.model = NULL;
// always idle in intermission
@ -602,15 +606,17 @@ V_CalcRefdef (viewstate_t *vs)
bob = V_CalcBob (vs);
// refresh position
r_data->refdef->viewposition = origin;
r_data->refdef->viewposition[2] += vs->height + bob;
origin = origin;
origin[2] += vs->height + bob;
// never let it sit exactly on a node line, because a water plane can
// disappear when viewed with the eye exactly on it.
// server protocol specifies to only 1/8 pixel, so add 1/16 in each axis
r_data->refdef->viewposition += (vec4f_t) { 1.0/16, 1.0/16, 1.0/16, 0};
origin += (vec4f_t) { 1.0/16, 1.0/16, 1.0/16, 0};
AngleQuat (vs->angles, &r_data->refdef->viewrotation[0]);//FIXME
vec4f_t rotation;
AngleQuat (vs->angles, &rotation[0]);//FIXME
Transform_SetWorldRotation (vs->camera_transform, rotation);
V_CalcViewRoll (vs);
V_AddIdle (vs);
@ -621,7 +627,7 @@ V_CalcRefdef (viewstate_t *vs)
// don't allow cheats in multiplayer
// FIXME check for dead
if (vs->voffs_enabled) {
r_data->refdef->viewposition += scr_ofsx->value * forward
origin += scr_ofsx->value * forward
+ scr_ofsy->value * right
+ scr_ofsz->value * up;
}
@ -629,23 +635,24 @@ V_CalcRefdef (viewstate_t *vs)
V_BoundOffsets (vs);
// set up gun position
vec4f_t gun_origin = vs->origin;
CalcGunAngle (vs);
origin += (vec4f_t) { 0, 0, vs->height, 0 };
origin += forward * bob * 0.4f + (vec4f_t) { 0, 0, bob, 0 };
gun_origin += (vec4f_t) { 0, 0, vs->height, 0 };
gun_origin += forward * bob * 0.4f + (vec4f_t) { 0, 0, bob, 0 };
// fudge position around to keep amount of weapon visible
// roughly equal with different FOV
if (hud_sbar->int_val == 0 && r_data->scr_viewsize->int_val >= 100) {
;
} else if (r_data->scr_viewsize->int_val == 110) {
origin += (vec4f_t) { 0, 0, 1, 0};
gun_origin += (vec4f_t) { 0, 0, 1, 0};
} else if (r_data->scr_viewsize->int_val == 100) {
origin += (vec4f_t) { 0, 0, 2, 0};
gun_origin += (vec4f_t) { 0, 0, 2, 0};
} else if (r_data->scr_viewsize->int_val == 90) {
origin += (vec4f_t) { 0, 0, 1, 0};
gun_origin += (vec4f_t) { 0, 0, 1, 0};
} else if (r_data->scr_viewsize->int_val == 80) {
origin += (vec4f_t) { 0, 0, 0.5, 0};
gun_origin += (vec4f_t) { 0, 0, 0.5, 0};
}
model_t *model = vs->weapon_model;
@ -660,29 +667,30 @@ V_CalcRefdef (viewstate_t *vs)
view->renderer.skin = 0;
// set up the refresh position
r_data->refdef->viewrotation = qmulf (vs->punchangle,
r_data->refdef->viewrotation);
Transform_SetWorldRotation (vs->camera_transform,
qmulf (vs->punchangle, rotation));
// smooth out stair step ups
if ((vs->onground != -1) && (origin[2] - oldz > 0)) {
if ((vs->onground != -1) && (gun_origin[2] - oldz > 0)) {
float steptime;
steptime = vs->frametime;
oldz += steptime * 80;
if (oldz > origin[2])
oldz = origin[2];
if (origin[2] - oldz > 12)
oldz = origin[2] - 12;
r_data->refdef->viewposition[2] += oldz - origin[2];
origin[2] += oldz - origin[2];
if (oldz > gun_origin[2])
oldz = gun_origin[2];
if (gun_origin[2] - oldz > 12)
oldz = gun_origin[2] - 12;
origin[2] += oldz - gun_origin[2];
gun_origin[2] += oldz - gun_origin[2];
} else {
oldz = origin[2];
oldz = gun_origin[2];
}
Transform_SetWorldPosition (vs->camera_transform, origin);
{
// FIXME sort out the alias model specific negation
vec3_t ang = {-viewangles[0], viewangles[1], viewangles[2]};
CL_TransformEntity (view, 1, ang, origin);
CL_TransformEntity (view, 1, ang, gun_origin);
}
if (vs->chase && chase_active->int_val) {
@ -724,8 +732,9 @@ void
V_RenderView (viewstate_t *vs)
{
if (!vs->active) {
r_data->refdef->viewposition = (vec4f_t) { 0, 0, 0, 1 };
r_data->refdef->viewrotation = (vec4f_t) { 0, 0, 0, 1 };
vec4f_t base = { 0, 0, 0, 1 };
Transform_SetWorldPosition (vs->camera_transform, base);
Transform_SetWorldRotation (vs->camera_transform, base);
return;
}
@ -752,6 +761,8 @@ V_Init (viewstate_t *viewstate)
"currently being displayed.\n"
"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);
}
void

View file

@ -44,6 +44,7 @@
#include "QF/screen.h"
#include "QF/sys.h"
#include "QF/scene/transform.h"
#include "QF/ui/view.h"
#include "compat.h"
@ -199,12 +200,20 @@ SCR_CalcRefdef (void)
needs almost the entire 256k of stack space!
*/
void
SCR_UpdateScreen (double realtime, SCR_Func *scr_funcs)
SCR_UpdateScreen (transform_t *camera, double realtime, SCR_Func *scr_funcs)
{
if (scr_skipupdate || !scr_initialized) {
return;
}
if (camera) {
r_data->refdef->viewposition = Transform_GetWorldPosition (camera);
r_data->refdef->viewrotation = Transform_GetWorldRotation (camera);
} else {
r_data->refdef->viewposition = (vec4f_t) { 0, 0, 0, 1 };
r_data->refdef->viewrotation = (vec4f_t) { 0, 0, 0, 1 };
}
r_data->realtime = realtime;
scr_copytop = r_data->scr_copyeverything = 0;

View file

@ -46,7 +46,6 @@ nq_cl_plugin_LIBS= \
nq_client_LIBFILES= \
libs/gib/libQFgib_client.la \
libs/scene/libQFscene.la \
libs/audio/libQFcd.la \
libs/audio/libQFsound.la
@ -55,6 +54,7 @@ nq_server_LIBFILES= \
libs/models/libQFmodels.la
nq_common_LIBFILES= \
libs/scene/libQFscene.la \
libs/net/libnet_main.la \
libs/console/libQFconsole.la \
libs/image/libQFimage.la \

View file

@ -199,7 +199,9 @@ CL_ClearState (void)
}
// wipe the entire cl structure
__auto_type cam = cl.viewstate.camera_transform;
memset (&cl, 0, sizeof (cl));
cl.viewstate.camera_transform = cam;
cl.viewstate.chase = 1;
cl.viewstate.chasestate = &cl.chasestate;
cl.watervis = 1;

View file

@ -46,6 +46,7 @@
#include "QF/plugin/vid_render.h"
#include "QF/scene/transform.h"
#include "QF/ui/view.h"
#include "sbar.h"
@ -75,9 +76,10 @@ SCR_CShift (void)
int contents = CONTENTS_EMPTY;
if (cls.state == ca_active && cl.worldmodel) {
vec4f_t origin;
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
//FIXME
leaf = Mod_PointInLeaf (&r_data->refdef->viewposition[0],
cl.worldmodel);
leaf = Mod_PointInLeaf (&origin[0], cl.worldmodel);
contents = leaf->contents;
}
V_SetContentsColor (&cl.viewstate, contents);
@ -167,5 +169,6 @@ CL_UpdateScreen (double realtime)
cl.viewstate.intermission = cl.intermission != 0;
V_PrepBlend (&cl.viewstate);
V_RenderView (&cl.viewstate);
SCR_UpdateScreen (realtime, scr_funcs[index]);
SCR_UpdateScreen (cl.viewstate.camera_transform,
realtime, scr_funcs[index]);
}

View file

@ -54,6 +54,7 @@
#include "QF/plugin/console.h"
#include "QF/plugin/vid_render.h"
#include "QF/scene/transform.h"
#include "buildnum.h"
#include "compat.h"
@ -504,7 +505,9 @@ Host_ClearMemory (void)
cls.signon = 0;
memset (&sv, 0, sizeof (sv));
__auto_type cam = cl.viewstate.camera_transform;
memset (&cl, 0, sizeof (cl));
cl.viewstate.camera_transform = cam;
}
/*
@ -606,15 +609,16 @@ Host_ClientFrame (void)
if (cls.state == ca_active) {
mleaf_t *l;
byte *asl = 0;
vec4f_t origin;
l = Mod_PointInLeaf (r_data->origin, cl.worldmodel);
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
l = Mod_PointInLeaf (&origin[0], cl.worldmodel);//FIXME
if (l)
asl = l->ambient_sound_level;
S_Update (r_data->origin, r_data->vpn, r_data->vright, r_data->vup,
asl);
S_Update (cl.viewstate.camera_transform, asl);
r_funcs->R_DecayLights (host_frametime);
} else
S_Update (vec3_origin, vec3_origin, vec3_origin, vec3_origin, 0);
S_Update (0, 0);
CDAudio_Update ();

View file

@ -141,8 +141,7 @@ IN_ProcessEvents (void)
}
void
S_Update (const vec3_t origin, const vec3_t v_forward, const vec3_t v_right,
const vec3_t v_up, const byte *ambient_sound_level)
S_Update (struct transform_s *ere, const byte *ambient_sound_level)
{
}

View file

@ -90,6 +90,7 @@
#include "QF/gib.h"
#include "QF/plugin/console.h"
#include "QF/scene/transform.h"
#include "buildnum.h"
#include "compat.h"
@ -389,7 +390,9 @@ CL_ClearState (void)
Info_Destroy (cl.serverinfo);
if (cl.players)
free (cl.players);
__auto_type cam = cl.viewstate.camera_transform;
memset (&cl, 0, sizeof (cl));
cl.viewstate.camera_transform = cam;
cl.players = calloc (MAX_CLIENTS, sizeof (player_info_t));
r_data->force_fullscreen = 0;
@ -1714,15 +1717,16 @@ Host_Frame (float time)
if (cls.state == ca_active) {
mleaf_t *l;
byte *asl = 0;
vec4f_t origin;
l = Mod_PointInLeaf (r_data->origin, cl.worldmodel);
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
l = Mod_PointInLeaf (&origin[0], cl.worldmodel);//FIXME
if (l)
asl = l->ambient_sound_level;
S_Update (r_data->origin, r_data->vpn, r_data->vright, r_data->vup,
asl);
S_Update (cl.viewstate.camera_transform, asl);
r_funcs->R_DecayLights (host_frametime);
} else
S_Update (vec3_origin, vec3_origin, vec3_origin, vec3_origin, 0);
S_Update (0, 0);
CDAudio_Update ();

View file

@ -44,6 +44,7 @@
#include "QF/pcx.h"
#include "QF/screen.h"
#include "QF/scene/transform.h"
#include "QF/ui/view.h"
#include "sbar.h"
@ -77,9 +78,10 @@ SCR_CShift (void)
int contents = CONTENTS_EMPTY;
if (cls.state == ca_active && cl.worldmodel) {
vec4f_t origin;
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
//FIXME
leaf = Mod_PointInLeaf (&r_data->refdef->viewposition[0],
cl.worldmodel);
leaf = Mod_PointInLeaf (&origin[0], cl.worldmodel);
contents = leaf->contents;
}
V_SetContentsColor (&cl.viewstate, contents);
@ -200,5 +202,6 @@ CL_UpdateScreen (double realtime)
cl.viewstate.intermission = cl.intermission != 0;
V_PrepBlend (&cl.viewstate);
V_RenderView (&cl.viewstate);
SCR_UpdateScreen (realtime, scr_funcs[index]);
SCR_UpdateScreen (cl.viewstate.camera_transform,
realtime, scr_funcs[index]);
}

View file

@ -109,7 +109,7 @@ bi_refresh (progs_t *pr, void *_res)
IN_ProcessEvents ();
//GIB_Thread_Execute ();
Cbuf_Execute_Stack (qwaq_cbuf);
SCR_UpdateScreen (con_realtime, bi_2dfuncs);
SCR_UpdateScreen (0, con_realtime, bi_2dfuncs);
R_FLOAT (pr) = con_frametime;
}