From e193ac2c043f15caa16394395d5789e54b0fbdce Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Sat, 23 Feb 2019 21:49:46 +0300 Subject: [PATCH] ref: more @mittorn's changes on RefAPI --- common/com_image.h | 109 ++ common/com_model.h | 34 +- common/ref_api.h | 26 +- common/xash3d_types.h | 92 ++ engine/client/cl_efx.c | 2115 +++++++++++++++++++++++++++++++++ engine/client/cl_frame.c | 4 +- engine/client/cl_game.c | 10 +- engine/client/cl_scrn.c | 1 - engine/client/cl_tent.c | 3 + engine/client/client.h | 26 - engine/client/ref_common.c | 11 +- engine/client/ref_common.h | 9 +- engine/client/vid_common.c | 532 +-------- engine/client/vid_common.h | 78 +- engine/common/common.h | 185 +-- engine/common/mod_local.h | 19 - engine/common/system.h | 13 - engine/platform/sdl/vid_sdl.c | 36 +- ref_gl/gl_alias.c | 5 +- ref_gl/gl_backend.c | 23 +- ref_gl/gl_beams.c | 1118 ++++------------- ref_gl/gl_context.c | 3 +- ref_gl/gl_cull.c | 4 +- ref_gl/gl_dbghulls.c | 10 +- ref_gl/gl_decals.c | 6 +- ref_gl/gl_draw.c | 4 +- ref_gl/gl_frustum.c | 1 - ref_gl/gl_image.c | 2 - ref_gl/gl_local.h | 83 +- ref_gl/gl_opengl.c | 518 ++++++++ ref_gl/gl_refrag.c | 6 +- ref_gl/gl_rlight.c | 8 +- ref_gl/gl_rmain.c | 48 +- ref_gl/gl_rmath.c | 2 - ref_gl/gl_rmisc.c | 20 +- ref_gl/gl_rpart.c | 1320 +------------------- ref_gl/gl_rsurf.c | 96 +- ref_gl/gl_sprite.c | 2 - ref_gl/gl_studio.c | 17 +- ref_gl/gl_warp.c | 9 +- ref_gl/wscript | 3 +- wscript | 2 +- 42 files changed, 3424 insertions(+), 3189 deletions(-) create mode 100644 common/com_image.h create mode 100644 engine/client/cl_efx.c create mode 100644 ref_gl/gl_opengl.c diff --git a/common/com_image.h b/common/com_image.h new file mode 100644 index 00000000..f9a8eeb3 --- /dev/null +++ b/common/com_image.h @@ -0,0 +1,109 @@ +#pragma once +/* +======================================================================== + +internal image format + +typically expanded to rgba buffer +NOTE: number at end of pixelformat name it's a total bitscount e.g. PF_RGB_24 == PF_RGB_888 +======================================================================== +*/ +#define ImageRAW( type ) (type == PF_RGBA_32 || type == PF_BGRA_32 || type == PF_RGB_24 || type == PF_BGR_24) +#define ImageDXT( type ) (type == PF_DXT1 || type == PF_DXT3 || type == PF_DXT5 || type == PF_ATI2) + +typedef enum +{ + PF_UNKNOWN = 0, + PF_INDEXED_24, // inflated palette (768 bytes) + PF_INDEXED_32, // deflated palette (1024 bytes) + PF_RGBA_32, // normal rgba buffer + PF_BGRA_32, // big endian RGBA (MacOS) + PF_RGB_24, // uncompressed dds or another 24-bit image + PF_BGR_24, // big-endian RGB (MacOS) + PF_DXT1, // s3tc DXT1 format + PF_DXT3, // s3tc DXT3 format + PF_DXT5, // s3tc DXT5 format + PF_ATI2, // latc ATI2N format + PF_TOTALCOUNT, // must be last +} pixformat_t; + +typedef struct bpc_desc_s +{ + int format; // pixelformat + char name[16]; // used for debug + uint glFormat; // RGBA format + int bpp; // channels (e.g. rgb = 3, rgba = 4) +} bpc_desc_t; + +// imagelib global settings +typedef enum +{ + IL_USE_LERPING = BIT(0), // lerping images during resample + IL_KEEP_8BIT = BIT(1), // don't expand paletted images + IL_ALLOW_OVERWRITE = BIT(2), // allow to overwrite stored images + IL_DONTFLIP_TGA = BIT(3), // Steam background completely ignore tga attribute 0x20 (stupid lammers!) + IL_DDS_HARDWARE = BIT(4), // DXT compression is support + IL_LOAD_DECAL = BIT(5), // special mode for load gradient decals + IL_OVERVIEW = BIT(6), // overview required some unque operations +} ilFlags_t; + +// goes into rgbdata_t->encode +#define DXT_ENCODE_DEFAULT 0 // don't use custom encoders +#define DXT_ENCODE_COLOR_YCoCg 0x1A01 // make sure that value dosn't collide with anything +#define DXT_ENCODE_ALPHA_1BIT 0x1A02 // normal 1-bit alpha +#define DXT_ENCODE_ALPHA_8BIT 0x1A03 // normal 8-bit alpha +#define DXT_ENCODE_ALPHA_SDF 0x1A04 // signed distance field +#define DXT_ENCODE_NORMAL_AG_ORTHO 0x1A05 // orthographic projection +#define DXT_ENCODE_NORMAL_AG_STEREO 0x1A06 // stereographic projection +#define DXT_ENCODE_NORMAL_AG_PARABOLOID 0x1A07 // paraboloid projection +#define DXT_ENCODE_NORMAL_AG_QUARTIC 0x1A08 // newton method +#define DXT_ENCODE_NORMAL_AG_AZIMUTHAL 0x1A09 // Lambert Azimuthal Equal-Area + +// rgbdata output flags +typedef enum +{ + // rgbdata->flags + IMAGE_CUBEMAP = BIT(0), // it's 6-sides cubemap buffer + IMAGE_HAS_ALPHA = BIT(1), // image contain alpha-channel + IMAGE_HAS_COLOR = BIT(2), // image contain RGB-channel + IMAGE_COLORINDEX = BIT(3), // all colors in palette is gradients of last color (decals) + IMAGE_HAS_LUMA = BIT(4), // image has luma pixels (q1-style maps) + IMAGE_SKYBOX = BIT(5), // only used by FS_SaveImage - for write right suffixes + IMAGE_QUAKESKY = BIT(6), // it's a quake sky double layered clouds (so keep it as 8 bit) + IMAGE_DDS_FORMAT = BIT(7), // a hint for GL loader + IMAGE_MULTILAYER = BIT(8), // to differentiate from 3D texture + IMAGE_ONEBIT_ALPHA = BIT(9), // binary alpha + IMAGE_QUAKEPAL = BIT(10), // image has quake1 palette + + // Image_Process manipulation flags + IMAGE_FLIP_X = BIT(16), // flip the image by width + IMAGE_FLIP_Y = BIT(17), // flip the image by height + IMAGE_ROT_90 = BIT(18), // flip from upper left corner to down right corner + IMAGE_ROT180 = IMAGE_FLIP_X|IMAGE_FLIP_Y, + IMAGE_ROT270 = IMAGE_FLIP_X|IMAGE_FLIP_Y|IMAGE_ROT_90, + IMAGE_EMBOSS = BIT(19), // apply emboss mapping + IMAGE_RESAMPLE = BIT(20), // resample image to specified dims +// reserved +// reserved + IMAGE_FORCE_RGBA = BIT(23), // force image to RGBA buffer + IMAGE_MAKE_LUMA = BIT(24), // create luma texture from indexed + IMAGE_QUANTIZE = BIT(25), // make indexed image from 24 or 32- bit image + IMAGE_LIGHTGAMMA = BIT(26), // apply gamma for image + IMAGE_REMAP = BIT(27), // interpret width and height as top and bottom color +} imgFlags_t; + +typedef struct rgbdata_s +{ + word width; // image width + word height; // image height + word depth; // image depth + uint type; // compression type + uint flags; // misc image flags + word encode; // DXT may have custom encoder, that will be decoded in GLSL-side + byte numMips; // mipmap count + byte *palette; // palette if present + byte *buffer; // image buffer + rgba_t fogParams; // some water textures in hl1 has info about fog color and alpha + size_t size; // for bounds checking +} rgbdata_t; + diff --git a/common/com_model.h b/common/com_model.h index 6642722c..0520c563 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -495,4 +495,36 @@ typedef struct maliasframedesc_t frames[1]; // variable sized } aliashdr_t; -#endif//COM_MODEL_H \ No newline at end of file + + +// remapping info +#define SUIT_HUE_START 192 +#define SUIT_HUE_END 223 +#define PLATE_HUE_START 160 +#define PLATE_HUE_END 191 + +#define SHIRT_HUE_START 16 +#define SHIRT_HUE_END 32 +#define PANTS_HUE_START 96 +#define PANTS_HUE_END 112 + + +// 1/32 epsilon to keep floating point happy +#define DIST_EPSILON (1.0f / 32.0f) +#define FRAC_EPSILON (1.0f / 1024.0f) +#define BACKFACE_EPSILON 0.01f +#define MAX_BOX_LEAFS 256 +#define ANIM_CYCLE 2 +#define MOD_FRAMES 20 + + + +#define MAX_DEMOS 32 +#define MAX_MOVIES 8 +#define MAX_CDTRACKS 32 +#define MAX_CLIENT_SPRITES 256 // SpriteTextures +#define MAX_EFRAGS 8192 // Arcane Dimensions required +#define MAX_REQUESTS 64 + + +#endif//COM_MODEL_H diff --git a/common/ref_api.h b/common/ref_api.h index d30f03d3..586925dd 100644 --- a/common/ref_api.h +++ b/common/ref_api.h @@ -15,7 +15,7 @@ GNU General Public License for more details. #pragma once #ifndef REF_API #define REF_API - +#include "com_image.h" #include "vgui_api.h" #include "render_api.h" #include "triangleapi.h" @@ -27,6 +27,21 @@ GNU General Public License for more details. #define REF_API_VERSION 1 + +#define TF_SKY (TF_SKYSIDE|TF_NOMIPMAP) +#define TF_FONT (TF_NOMIPMAP|TF_CLAMP) +#define TF_IMAGE (TF_NOMIPMAP|TF_CLAMP) +#define TF_DECAL (TF_CLAMP) + + +// screenshot types +#define VID_SCREENSHOT 0 +#define VID_LEVELSHOT 1 +#define VID_MINISHOT 2 +#define VID_MAPSHOT 3 // special case for overview layer +#define VID_SNAPSHOT 4 // save screenshot into root dir and no gamma correction + + typedef struct ref_globals_s { qboolean developer; @@ -108,6 +123,7 @@ typedef struct ref_interface_s void (*GL_SetRenderMode)( int renderMode ); int (*R_AddEntity)( int entityType, cl_entity_t *ent ); + void (*CL_AddCustomBeam)( cl_entity_t *pEnvBeam ); // view info qboolean (*IsNormalPass)( void ); @@ -156,10 +172,12 @@ typedef struct ref_interface_s // studio interface float (*R_StudioEstimateFrame)( cl_entity_t *e, mstudioseqdesc_t *pseqdesc ); void (*R_StudioLerpMovement)( cl_entity_t *e, double time, vec3_t origin, vec3_t angles ); + void (*CL_InitStudioAPI)( void ); // bmodel void (*R_InitSkyClouds)( struct mip_s *mt, struct texture_s *tx, qboolean custom_palette ); void (*GL_SubdivideSurface)( msurface_t *fa ); + void (*CL_RunLightStyles)( void ); // sprites void (*R_GetSpriteParms)( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite ); @@ -175,6 +193,12 @@ typedef struct ref_interface_s // particle renderer void (*CL_Particle)( const vec3_t origin, int color, float life, int zpos, int zvel ); // debug thing + // efx implementation + void (*CL_DrawParticles)( double frametime, particle_t *particles ); + void (*CL_DrawTracers)( double frametime, particle_t *tracers ); + void (*CL_DrawBeams)( int fTrans , BEAM *beams ); + qboolean (*R_BeamCull)( const vec3_t start, const vec3_t end, qboolean pvsOnly ); + // Xash3D Render Interface render_api_t *RenderAPI; // partial RenderAPI implementation render_interface_t *RenderIface; // compatible RenderInterface implementation: renderer should call client RenderInterface by itself diff --git a/common/xash3d_types.h b/common/xash3d_types.h index 18966222..b13a3153 100644 --- a/common/xash3d_types.h +++ b/common/xash3d_types.h @@ -1,6 +1,7 @@ // basic typedefs #ifndef XASH_TYPES_H #define XASH_TYPES_H + typedef unsigned char byte; typedef int sound_t; typedef float vec_t; @@ -30,4 +31,95 @@ typedef Uint64 integer64; typedef unsigned long long integer64; #endif typedef integer64 longtime_t; + +#define MAX_STRING 256 // generic string +#define MAX_INFO_STRING 256 // infostrings are transmitted across network +#define MAX_SERVERINFO_STRING 512 // server handles too many settings. expand to 1024? +#define MAX_LOCALINFO_STRING 32768 // localinfo used on server and not sended to the clients +#define MAX_SYSPATH 1024 // system filepath +#define MAX_PRINT_MSG 8192 // how many symbols can handle single call of Con_Printf or Con_DPrintf +#define MAX_TOKEN 2048 // parse token length +#define MAX_MODS 512 // environment games that engine can keep visible +#define MAX_USERMSG_LENGTH 2048 // don't modify it's relies on a client-side definitions + +#define BIT( n ) ( 1 << ( n )) +#define GAMMA ( 2.2 ) // Valve Software gamma +#define INVGAMMA ( 1.0 / 2.2 ) // back to 1.0 +#define TEXGAMMA ( 0.9 ) // compensate dim textures +#define SetBits( iBitVector, bits ) ((iBitVector) = (iBitVector) | (bits)) +#define ClearBits( iBitVector, bits ) ((iBitVector) = (iBitVector) & ~(bits)) +#define FBitSet( iBitVector, bit ) ((iBitVector) & (bit)) + +#ifndef __cplusplus +#ifdef NULL +#undef NULL +#endif + +#define NULL ((void *)0) +#endif + +// color strings +#define IsColorString( p ) ( p && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' ) +#define ColorIndex( c ) ((( c ) - '0' ) & 7 ) + +#if defined __i386__ && defined __GNUC__ +#define GAME_EXPORT __attribute__((force_align_arg_pointer)) +#else +#define GAME_EXPORT +#endif + + +#ifdef XASH_BIG_ENDIAN +#define LittleLong(x) (((int)(((x)&255)<<24)) + ((int)((((x)>>8)&255)<<16)) + ((int)(((x)>>16)&255)<<8) + (((x) >> 24)&255)) +#define LittleLongSW(x) (x = LittleLong(x) ) +#define LittleShort(x) ((short)( (((short)(x) >> 8) & 255) + (((short)(x) & 255) << 8))) +#define LittleShortSW(x) (x = LittleShort(x) ) +_inline float LittleFloat( float f ) +{ + union + { + float f; + unsigned char b[4]; + } dat1, dat2; + + dat1.f = f; + dat2.b[0] = dat1.b[3]; + dat2.b[1] = dat1.b[2]; + dat2.b[2] = dat1.b[1]; + dat2.b[3] = dat1.b[0]; + + return dat2.f; +} +#else +#define LittleLong(x) (x) +#define LittleLongSW(x) +#define LittleShort(x) (x) +#define LittleShortSW(x) +#define LittleFloat(x) (x) +#endif + + +typedef unsigned int dword; +typedef unsigned int uint; +typedef char string[MAX_STRING]; +typedef struct file_s file_t; // normal file +typedef struct wfile_s wfile_t; // wad file +typedef struct stream_s stream_t; // sound stream for background music playing +typedef off_t fs_offset_t; + +typedef struct dllfunc_s +{ + const char *name; + void **func; +} dllfunc_t; + +typedef struct dll_info_s +{ + const char *name; // name of library + const dllfunc_t *fcts; // list of dll exports + qboolean crash; // crash if dll not found + void *link; // hinstance of loading library +} dll_info_t; + + #endif // XASH_TYPES_H diff --git a/engine/client/cl_efx.c b/engine/client/cl_efx.c new file mode 100644 index 00000000..94378c75 --- /dev/null +++ b/engine/client/cl_efx.c @@ -0,0 +1,2115 @@ + + +#include "common.h" +#include "client.h" +#include "customentity.h" +#include "r_efx.h" +#include "cl_tent.h" +#include "pm_local.h" +#define PART_SIZE Q_max( 0.5f, cl_draw_particles->value ) + +/* +============================================================== + +PARTICLES MANAGEMENT + +============================================================== +*/ +// particle ramps +static int ramp1[8] = { 0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61 }; +static int ramp2[8] = { 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66 }; +static int ramp3[6] = { 0x6d, 0x6b, 6, 5, 4, 3 }; +static float gTracerSize[11] = { 1.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; +static int gSparkRamp[9] = { 0xfe, 0xfd, 0xfc, 0x6f, 0x6e, 0x6d, 0x6c, 0x67, 0x60 }; + +static color24 gTracerColors[] = +{ +{ 255, 255, 255 }, // White +{ 255, 0, 0 }, // Red +{ 0, 255, 0 }, // Green +{ 0, 0, 255 }, // Blue +{ 0, 0, 0 }, // Tracer default, filled in from cvars, etc. +{ 255, 167, 17 }, // Yellow-orange sparks +{ 255, 130, 90 }, // Yellowish streaks (garg) +{ 55, 60, 144 }, // Blue egon streak +{ 255, 130, 90 }, // More Yellowish streaks (garg) +{ 255, 140, 90 }, // More Yellowish streaks (garg) +{ 200, 130, 90 }, // More red streaks (garg) +{ 255, 120, 70 }, // Darker red streaks (garg) +}; + +convar_t *tracerred; +convar_t *tracergreen; +convar_t *tracerblue; +convar_t *traceralpha; +convar_t *tracerspeed; +convar_t *tracerlength; +convar_t *traceroffset; + +particle_t *cl_active_particles; +particle_t *cl_active_tracers; +particle_t *cl_free_particles; +particle_t *cl_particles = NULL; // particle pool +static vec3_t cl_avelocities[NUMVERTEXNORMALS]; +static float cl_lasttimewarn = 0.0f; + +/* +================ +R_LookupColor + +find nearest color in particle palette +================ +*/ +short R_LookupColor( byte r, byte g, byte b ) +{ + int i, best; + float diff, bestdiff; + float rf, gf, bf; + + bestdiff = 999999; + best = 65535; + + for( i = 0; i < 256; i++ ) + { + rf = r - clgame.palette[i].r; + gf = g - clgame.palette[i].g; + bf = b - clgame.palette[i].b; + + // convert color to monochrome + diff = rf * (rf * 0.2) + gf * (gf * 0.5) + bf * (bf * 0.3); + + if ( diff < bestdiff ) + { + bestdiff = diff; + best = i; + } + } + + return best; +} + +/* +================ +R_GetPackedColor + +in hardware mode does nothing +================ +*/ +void R_GetPackedColor( short *packed, short color ) +{ + if( packed ) *packed = 0; +} + +/* +================ +CL_InitParticles + +================ +*/ +void CL_InitParticles( void ) +{ + int i; + + cl_particles = Mem_Calloc( cls.mempool, sizeof( particle_t ) * GI->max_particles ); + CL_ClearParticles (); + + // this is used for EF_BRIGHTFIELD + for( i = 0; i < NUMVERTEXNORMALS; i++ ) + { + cl_avelocities[i][0] = COM_RandomFloat( 0.0f, 2.55f ); + cl_avelocities[i][1] = COM_RandomFloat( 0.0f, 2.55f ); + cl_avelocities[i][2] = COM_RandomFloat( 0.0f, 2.55f ); + } + + tracerred = Cvar_Get( "tracerred", "0.8", 0, "tracer red component weight ( 0 - 1.0 )" ); + tracergreen = Cvar_Get( "tracergreen", "0.8", 0, "tracer green component weight ( 0 - 1.0 )" ); + tracerblue = Cvar_Get( "tracerblue", "0.4", 0, "tracer blue component weight ( 0 - 1.0 )" ); + traceralpha = Cvar_Get( "traceralpha", "0.5", 0, "tracer alpha amount ( 0 - 1.0 )" ); + tracerspeed = Cvar_Get( "tracerspeed", "6000", 0, "tracer speed" ); + tracerlength = Cvar_Get( "tracerlength", "0.8", 0, "tracer length factor" ); + traceroffset = Cvar_Get( "traceroffset", "30", 0, "tracer starting offset" ); +} + +/* +================ +CL_ClearParticles + +================ +*/ +void CL_ClearParticles( void ) +{ + int i; + + if( !cl_particles ) return; + + cl_free_particles = cl_particles; + cl_active_particles = NULL; + cl_active_tracers = NULL; + + for( i = 0; i < GI->max_particles - 1; i++ ) + cl_particles[i].next = &cl_particles[i+1]; + + cl_particles[GI->max_particles-1].next = NULL; +} + +/* +================ +CL_FreeParticles + +================ +*/ +void CL_FreeParticles( void ) +{ + if( cl_particles ) + Mem_Free( cl_particles ); + cl_particles = NULL; +} + +/* +================ +CL_FreeParticle + +move particle to freelist +================ +*/ +void CL_FreeParticle( particle_t *p ) +{ + if( p->deathfunc ) + { + // call right the deathfunc before die + p->deathfunc( p ); + p->deathfunc = NULL; + } + + p->next = cl_free_particles; + cl_free_particles = p; +} + +/* +================ +R_AllocParticle + +can return NULL if particles is out +================ +*/ +particle_t *R_AllocParticle( void (*callback)( particle_t*, float )) +{ + particle_t *p; + + if( !cl_draw_particles->value ) + return NULL; + + // never alloc particles when we not in game +// if( tr.frametime == 0.0 ) return NULL; + + if( !cl_free_particles ) + { + if( cl_lasttimewarn < host.realtime ) + { + // don't spam about overflow + Con_DPrintf( S_ERROR "Overflow %d particles\n", GI->max_particles ); + cl_lasttimewarn = host.realtime + 1.0f; + } + return NULL; + } + + p = cl_free_particles; + cl_free_particles = p->next; + p->next = cl_active_particles; + cl_active_particles = p; + + // clear old particle + p->type = pt_static; + VectorClear( p->vel ); + VectorClear( p->org ); + p->packedColor = 0; + p->die = cl.time; + p->color = 0; + p->ramp = 0; + + if( callback ) + { + p->type = pt_clientcustom; + p->callback = callback; + } + + return p; +} + +/* +================ +R_AllocTracer + +can return NULL if particles is out +================ +*/ +particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life ) +{ + particle_t *p; + + if( !cl_draw_tracers->value ) + return NULL; + + // never alloc particles when we not in game + //if( tr.frametime == 0.0 ) return NULL; + + if( !cl_free_particles ) + { + if( cl_lasttimewarn < host.realtime ) + { + // don't spam about overflow + Con_DPrintf( S_ERROR "Overflow %d tracers\n", GI->max_particles ); + cl_lasttimewarn = host.realtime + 1.0f; + } + return NULL; + } + + p = cl_free_particles; + cl_free_particles = p->next; + p->next = cl_active_tracers; + cl_active_tracers = p; + + // clear old particle + p->type = pt_static; + VectorCopy( org, p->org ); + VectorCopy( vel, p->vel ); + p->die = cl.time + life; + p->ramp = tracerlength->value; + p->color = 4; // select custom color + p->packedColor = 255; // alpha + + return p; +} +/* +============================================================== + +VIEWBEAMS MANAGEMENT + +============================================================== +*/ +BEAM *cl_active_beams; +BEAM *cl_free_beams; +BEAM *cl_viewbeams = NULL; // beams pool + + +/* +============================================================== + +BEAM ALLOCATE & PROCESSING + +============================================================== +*/ + + +/* +============== +R_BeamSetAttributes + +set beam attributes +============== +*/ +static void R_BeamSetAttributes( BEAM *pbeam, float r, float g, float b, float framerate, int startFrame ) +{ + pbeam->frame = (float)startFrame; + pbeam->frameRate = framerate; + pbeam->r = r; + pbeam->g = g; + pbeam->b = b; +} + + + +/* +============== +R_BeamAlloc + +============== +*/ +BEAM *R_BeamAlloc( void ) +{ + BEAM *pBeam; + + if( !cl_free_beams ) + return NULL; + + pBeam = cl_free_beams; + cl_free_beams = pBeam->next; + memset( pBeam, 0, sizeof( *pBeam )); + pBeam->next = cl_active_beams; + cl_active_beams = pBeam; + pBeam->die = cl.time; + + return pBeam; +} + +/* +============== +R_BeamFree + +============== +*/ +void R_BeamFree( BEAM *pBeam ) +{ + // free particles that have died off. + R_FreeDeadParticles( &pBeam->particles ); + + // now link into free list; + pBeam->next = cl_free_beams; + cl_free_beams = pBeam; +} + + +/* +================ +CL_InitViewBeams + +================ +*/ +void CL_InitViewBeams( void ) +{ + cl_viewbeams = Mem_Calloc( cls.mempool, sizeof( BEAM ) * GI->max_beams ); + CL_ClearViewBeams(); +} + +/* +================ +CL_ClearViewBeams + +================ +*/ +void CL_ClearViewBeams( void ) +{ + int i; + + if( !cl_viewbeams ) return; + + // clear beams + cl_free_beams = cl_viewbeams; + cl_active_beams = NULL; + + for( i = 0; i < GI->max_beams - 1; i++ ) + cl_viewbeams[i].next = &cl_viewbeams[i+1]; + cl_viewbeams[GI->max_beams - 1].next = NULL; +} + +/* +================ +CL_FreeViewBeams + +================ +*/ +void CL_FreeViewBeams( void ) +{ + if( cl_viewbeams ) + Mem_Free( cl_viewbeams ); + cl_viewbeams = NULL; +} + +/* +============== +R_BeamGetEntity + +extract entity number from index +handle user entities +============== +*/ +static cl_entity_t *R_BeamGetEntity( int index ) +{ + if( index < 0 ) + return clgame.dllFuncs.pfnGetUserEntity( BEAMENT_ENTITY( -index )); + return CL_GetEntityByIndex( BEAMENT_ENTITY( index )); +} + +/* +============== +CL_KillDeadBeams + +============== +*/ +void CL_KillDeadBeams( cl_entity_t *pDeadEntity ) +{ + BEAM *pbeam; + BEAM *pnewlist; + BEAM *pnext; + particle_t *pHead; // build a new list to replace cl_active_beams. + + pbeam = cl_active_beams; // old list. + pnewlist = NULL; // new list. + + while( pbeam ) + { + cl_entity_t *beament; + pnext = pbeam->next; + + // link into new list. + if( R_BeamGetEntity( pbeam->startEntity ) != pDeadEntity ) + { + pbeam->next = pnewlist; + pnewlist = pbeam; + + pbeam = pnext; + continue; + } + + pbeam->flags &= ~(FBEAM_STARTENTITY | FBEAM_ENDENTITY); + + if( pbeam->type != TE_BEAMFOLLOW ) + { + // remove beam + pbeam->die = cl.time - 0.1f; + + // kill off particles + pHead = pbeam->particles; + while( pHead ) + { + pHead->die = cl.time - 0.1f; + pHead = pHead->next; + } + + // free the beam + R_BeamFree( pbeam ); + } + else + { + // stay active + pbeam->next = pnewlist; + pnewlist = pbeam; + } + + pbeam = pnext; + } + + // We now have a new list with the bogus stuff released. + cl_active_beams = pnewlist; +} + + +/* +=============== +CL_ReadLineFile_f + +Optimized version of pointfile - use beams instead of particles +=============== +*/ +void CL_ReadLineFile_f( void ) +{ + char *afile, *pfile; + vec3_t p1, p2; + int count, modelIndex; + char filename[MAX_QPATH]; + model_t *model; + string token; + + Q_snprintf( filename, sizeof( filename ), "maps/%s.lin", clgame.mapname ); + afile = FS_LoadFile( filename, NULL, false ); + + if( !afile ) + { + Con_Printf( S_ERROR "couldn't open %s\n", filename ); + return; + } + + Con_Printf( "Reading %s...\n", filename ); + + count = 0; + pfile = afile; + model = CL_LoadModel( DEFAULT_LASERBEAM_PATH, &modelIndex ); + + while( 1 ) + { + pfile = COM_ParseFile( pfile, token ); + if( !pfile ) break; + p1[0] = Q_atof( token ); + + pfile = COM_ParseFile( pfile, token ); + if( !pfile ) break; + p1[1] = Q_atof( token ); + + pfile = COM_ParseFile( pfile, token ); + if( !pfile ) break; + p1[2] = Q_atof( token ); + + pfile = COM_ParseFile( pfile, token ); + if( !pfile ) break; + + if( token[0] != '-' ) + { + Con_Printf( S_ERROR "%s is corrupted\n", filename ); + break; + } + + pfile = COM_ParseFile( pfile, token ); + if( !pfile ) break; + p2[0] = Q_atof( token ); + + pfile = COM_ParseFile( pfile, token ); + if( !pfile ) break; + p2[1] = Q_atof( token ); + + pfile = COM_ParseFile( pfile, token ); + if( !pfile ) break; + p2[2] = Q_atof( token ); + + count++; + + if( !R_BeamPoints( p1, p2, modelIndex, 0, 2, 0, 255, 0, 0, 0, 255.0f, 0.0f, 0.0f )) + { + if( !model || model->type != mod_sprite ) + Con_Printf( S_ERROR "failed to load \"%s\"!\n", DEFAULT_LASERBEAM_PATH ); + else Con_Printf( S_ERROR "not enough free beams!\n" ); + break; + } + } + + Mem_Free( afile ); + + if( count ) Con_Printf( "%i lines read\n", count ); + else Con_Printf( "map %s has no leaks!\n", clgame.mapname ); +} + + +/* +============== +R_BeamSprite + +Create a beam with sprite at the end +Valve legacy +============== +*/ +static void CL_BeamSprite( vec3_t start, vec3_t end, int beamIndex, int spriteIndex ) +{ + R_BeamPoints( start, end, beamIndex, 0.01f, 0.4f, 0, COM_RandomFloat( 0.5f, 0.655f ), 5.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f ); + R_TempSprite( end, vec3_origin, 0.1f, spriteIndex, kRenderTransAdd, kRenderFxNone, 0.35f, 0.01f, 0.0f ); +} + + +/* +============== +R_BeamSetup + +generic function. all beams must be +passed through this +============== +*/ +static void R_BeamSetup( BEAM *pbeam, vec3_t start, vec3_t end, int modelIndex, float life, float width, float amplitude, float brightness, float speed ) +{ + model_t *sprite = CL_ModelHandle( modelIndex ); + + if( !sprite ) return; + + pbeam->type = BEAM_POINTS; + pbeam->modelIndex = modelIndex; + pbeam->frame = 0; + pbeam->frameRate = 0; + pbeam->frameCount = sprite->numframes; + + VectorCopy( start, pbeam->source ); + VectorCopy( end, pbeam->target ); + VectorSubtract( end, start, pbeam->delta ); + + pbeam->freq = speed * cl.time; + pbeam->die = life + cl.time; + pbeam->amplitude = amplitude; + pbeam->brightness = brightness; + pbeam->width = width; + pbeam->speed = speed; + + if( amplitude >= 0.50f ) + pbeam->segments = VectorLength( pbeam->delta ) * 0.25f + 3.0f; // one per 4 pixels + else pbeam->segments = VectorLength( pbeam->delta ) * 0.075f + 3.0f; // one per 16 pixels + + pbeam->pFollowModel = NULL; + pbeam->flags = 0; +} + +/* +============== +CL_BeamAttemptToDie + +Check for expired beams +============== +*/ +qboolean CL_BeamAttemptToDie( BEAM *pBeam ) +{ + Assert( pBeam != NULL ); + + // premanent beams never die automatically + if( FBitSet( pBeam->flags, FBEAM_FOREVER )) + return false; + + if( pBeam->type == TE_BEAMFOLLOW && pBeam->particles ) + { + // wait for all trails are dead + return false; + } + + // other beams + if( pBeam->die > cl.time ) + return false; + + return true; +} + +/* +============== +R_BeamKill + +Remove beam attached to specified entity +and all particle trails (if this is a beamfollow) +============== +*/ +void R_BeamKill( int deadEntity ) +{ + cl_entity_t *pDeadEntity; + + pDeadEntity = R_BeamGetEntity( deadEntity ); + if( !pDeadEntity ) return; + + CL_KillDeadBeams( pDeadEntity ); +} + +/* +============== +CL_ParseViewBeam + +handle beam messages +============== +*/ +void CL_ParseViewBeam( sizebuf_t *msg, int beamType ) +{ + vec3_t start, end; + int modelIndex, startFrame; + float frameRate, life, width; + int startEnt, endEnt; + float noise, speed; + float r, g, b, a; + + switch( beamType ) + { + case TE_BEAMPOINTS: + start[0] = MSG_ReadCoord( msg ); + start[1] = MSG_ReadCoord( msg ); + start[2] = MSG_ReadCoord( msg ); + end[0] = MSG_ReadCoord( msg ); + end[1] = MSG_ReadCoord( msg ); + end[2] = MSG_ReadCoord( msg ); + modelIndex = MSG_ReadShort( msg ); + startFrame = MSG_ReadByte( msg ); + frameRate = (float)MSG_ReadByte( msg ); + life = (float)(MSG_ReadByte( msg ) * 0.1f); + width = (float)(MSG_ReadByte( msg ) * 0.1f); + noise = (float)(MSG_ReadByte( msg ) * 0.01f); + r = (float)MSG_ReadByte( msg ) / 255.0f; + g = (float)MSG_ReadByte( msg ) / 255.0f; + b = (float)MSG_ReadByte( msg ) / 255.0f; + a = (float)MSG_ReadByte( msg ) / 255.0f; + speed = (float)(MSG_ReadByte( msg ) * 0.1f); + R_BeamPoints( start, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b ); + break; + case TE_BEAMENTPOINT: + startEnt = MSG_ReadShort( msg ); + end[0] = MSG_ReadCoord( msg ); + end[1] = MSG_ReadCoord( msg ); + end[2] = MSG_ReadCoord( msg ); + modelIndex = MSG_ReadShort( msg ); + startFrame = MSG_ReadByte( msg ); + frameRate = (float)MSG_ReadByte( msg ); + life = (float)(MSG_ReadByte( msg ) * 0.1f); + width = (float)(MSG_ReadByte( msg ) * 0.1f); + noise = (float)(MSG_ReadByte( msg ) * 0.01f); + r = (float)MSG_ReadByte( msg ) / 255.0f; + g = (float)MSG_ReadByte( msg ) / 255.0f; + b = (float)MSG_ReadByte( msg ) / 255.0f; + a = (float)MSG_ReadByte( msg ) / 255.0f; + speed = (float)(MSG_ReadByte( msg ) * 0.1f); + R_BeamEntPoint( startEnt, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b ); + break; + case TE_LIGHTNING: + start[0] = MSG_ReadCoord( msg ); + start[1] = MSG_ReadCoord( msg ); + start[2] = MSG_ReadCoord( msg ); + end[0] = MSG_ReadCoord( msg ); + end[1] = MSG_ReadCoord( msg ); + end[2] = MSG_ReadCoord( msg ); + life = (float)(MSG_ReadByte( msg ) * 0.1f); + width = (float)(MSG_ReadByte( msg ) * 0.1f); + noise = (float)(MSG_ReadByte( msg ) * 0.01f); + modelIndex = MSG_ReadShort( msg ); + R_BeamLightning( start, end, modelIndex, life, width, noise, 0.6F, 3.5f ); + break; + case TE_BEAMENTS: + startEnt = MSG_ReadShort( msg ); + endEnt = MSG_ReadShort( msg ); + modelIndex = MSG_ReadShort( msg ); + startFrame = MSG_ReadByte( msg ); + frameRate = (float)(MSG_ReadByte( msg ) * 0.1f); + life = (float)(MSG_ReadByte( msg ) * 0.1f); + width = (float)(MSG_ReadByte( msg ) * 0.1f); + noise = (float)(MSG_ReadByte( msg ) * 0.01f); + r = (float)MSG_ReadByte( msg ) / 255.0f; + g = (float)MSG_ReadByte( msg ) / 255.0f; + b = (float)MSG_ReadByte( msg ) / 255.0f; + a = (float)MSG_ReadByte( msg ) / 255.0f; + speed = (float)(MSG_ReadByte( msg ) * 0.1f); + R_BeamEnts( startEnt, endEnt, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b ); + break; + case TE_BEAM: + break; + case TE_BEAMSPRITE: + start[0] = MSG_ReadCoord( msg ); + start[1] = MSG_ReadCoord( msg ); + start[2] = MSG_ReadCoord( msg ); + end[0] = MSG_ReadCoord( msg ); + end[1] = MSG_ReadCoord( msg ); + end[2] = MSG_ReadCoord( msg ); + modelIndex = MSG_ReadShort( msg ); // beam model + startFrame = MSG_ReadShort( msg ); // sprite model + CL_BeamSprite( start, end, modelIndex, startFrame ); + break; + case TE_BEAMTORUS: + case TE_BEAMDISK: + case TE_BEAMCYLINDER: + start[0] = MSG_ReadCoord( msg ); + start[1] = MSG_ReadCoord( msg ); + start[2] = MSG_ReadCoord( msg ); + end[0] = MSG_ReadCoord( msg ); + end[1] = MSG_ReadCoord( msg ); + end[2] = MSG_ReadCoord( msg ); + modelIndex = MSG_ReadShort( msg ); + startFrame = MSG_ReadByte( msg ); + frameRate = (float)(MSG_ReadByte( msg )); + life = (float)(MSG_ReadByte( msg ) * 0.1f); + width = (float)(MSG_ReadByte( msg )); + noise = (float)(MSG_ReadByte( msg ) * 0.1f); + r = (float)MSG_ReadByte( msg ) / 255.0f; + g = (float)MSG_ReadByte( msg ) / 255.0f; + b = (float)MSG_ReadByte( msg ) / 255.0f; + a = (float)MSG_ReadByte( msg ) / 255.0f; + speed = (float)(MSG_ReadByte( msg ) / 0.1f); + R_BeamCirclePoints( beamType, start, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b ); + break; + case TE_BEAMFOLLOW: + startEnt = MSG_ReadShort( msg ); + modelIndex = MSG_ReadShort( msg ); + life = (float)(MSG_ReadByte( msg ) * 0.1f); + width = (float)MSG_ReadByte( msg ); + r = (float)MSG_ReadByte( msg ) / 255.0f; + g = (float)MSG_ReadByte( msg ) / 255.0f; + b = (float)MSG_ReadByte( msg ) / 255.0f; + a = (float)MSG_ReadByte( msg ) / 255.0f; + R_BeamFollow( startEnt, modelIndex, life, width, r, g, b, a ); + break; + case TE_BEAMRING: + startEnt = MSG_ReadShort( msg ); + endEnt = MSG_ReadShort( msg ); + modelIndex = MSG_ReadShort( msg ); + startFrame = MSG_ReadByte( msg ); + frameRate = (float)MSG_ReadByte( msg ); + life = (float)(MSG_ReadByte( msg ) * 0.1f); + width = (float)(MSG_ReadByte( msg ) * 0.1f); + noise = (float)(MSG_ReadByte( msg ) * 0.01f); + r = (float)MSG_ReadByte( msg ) / 255.0f; + g = (float)MSG_ReadByte( msg ) / 255.0f; + b = (float)MSG_ReadByte( msg ) / 255.0f; + a = (float)MSG_ReadByte( msg ) / 255.0f; + speed = (float)(MSG_ReadByte( msg ) * 0.1f); + R_BeamRing( startEnt, endEnt, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b ); + break; + case TE_BEAMHOSE: + break; + case TE_KILLBEAM: + startEnt = MSG_ReadShort( msg ); + R_BeamKill( startEnt ); + break; + } +} + + +/* +============== +R_BeamEnts + +Create beam between two ents +============== +*/ +BEAM *R_BeamEnts( int startEnt, int endEnt, int modelIndex, float life, float width, float amplitude, float brightness, + float speed, int startFrame, float framerate, float r, float g, float b ) +{ + cl_entity_t *start, *end; + BEAM *pbeam; + model_t *mod; + + mod = CL_ModelHandle( modelIndex ); + + // need a valid model. + if( !mod || mod->type != mod_sprite ) + return NULL; + + start = R_BeamGetEntity( startEnt ); + end = R_BeamGetEntity( endEnt ); + + if( !start || !end ) + return NULL; + + // don't start temporary beams out of the PVS + if( life != 0 && ( !start->model || !end->model )) + return NULL; + + pbeam = R_BeamLightning( vec3_origin, vec3_origin, modelIndex, life, width, amplitude, brightness, speed ); + if( !pbeam ) return NULL; + + pbeam->type = TE_BEAMPOINTS; + SetBits( pbeam->flags, FBEAM_STARTENTITY | FBEAM_ENDENTITY ); + if( life == 0 ) SetBits( pbeam->flags, FBEAM_FOREVER ); + + pbeam->startEntity = startEnt; + pbeam->endEntity = endEnt; + + R_BeamSetAttributes( pbeam, r, g, b, framerate, startFrame ); + + return pbeam; +} + +/* +============== +R_BeamPoints + +Create beam between two points +============== +*/ +BEAM *R_BeamPoints( vec3_t start, vec3_t end, int modelIndex, float life, float width, float amplitude, + float brightness, float speed, int startFrame, float framerate, float r, float g, float b ) +{ + BEAM *pbeam; + + if( life != 0 && ref.dllFuncs.R_BeamCull( start, end, true )) + return NULL; + + pbeam = R_BeamAlloc(); + if( !pbeam ) return NULL; + + pbeam->die = cl.time; + + if( modelIndex < 0 ) + return NULL; + + R_BeamSetup( pbeam, start, end, modelIndex, life, width, amplitude, brightness, speed ); + if( life == 0 ) SetBits( pbeam->flags, FBEAM_FOREVER ); + + R_BeamSetAttributes( pbeam, r, g, b, framerate, startFrame ); + + return pbeam; +} + +/* +============== +R_BeamCirclePoints + +Create beam cicrle +============== +*/ +BEAM *R_BeamCirclePoints( int type, vec3_t start, vec3_t end, int modelIndex, float life, float width, + float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b ) +{ + BEAM *pbeam = R_BeamLightning( start, end, modelIndex, life, width, amplitude, brightness, speed ); + + if( !pbeam ) return NULL; + pbeam->type = type; + if( life == 0 ) SetBits( pbeam->flags, FBEAM_FOREVER ); + R_BeamSetAttributes( pbeam, r, g, b, framerate, startFrame ); + + return pbeam; +} + + +/* +============== +R_BeamEntPoint + +Create beam between entity and point +============== +*/ +BEAM *R_BeamEntPoint( int startEnt, vec3_t end, int modelIndex, float life, float width, float amplitude, + float brightness, float speed, int startFrame, float framerate, float r, float g, float b ) +{ + BEAM *pbeam; + cl_entity_t *start; + + start = R_BeamGetEntity( startEnt ); + + if( !start ) return NULL; + + if( life == 0 && !start->model ) + return NULL; + + pbeam = R_BeamAlloc(); + if ( !pbeam ) return NULL; + + pbeam->die = cl.time; + if( modelIndex < 0 ) + return NULL; + + R_BeamSetup( pbeam, vec3_origin, end, modelIndex, life, width, amplitude, brightness, speed ); + + pbeam->type = TE_BEAMPOINTS; + SetBits( pbeam->flags, FBEAM_STARTENTITY ); + if( life == 0 ) SetBits( pbeam->flags, FBEAM_FOREVER ); + pbeam->startEntity = startEnt; + pbeam->endEntity = 0; + + R_BeamSetAttributes( pbeam, r, g, b, framerate, startFrame ); + + return pbeam; +} + +/* +============== +R_BeamRing + +Create beam between two ents +============== +*/ +BEAM *R_BeamRing( int startEnt, int endEnt, int modelIndex, float life, float width, float amplitude, float brightness, + float speed, int startFrame, float framerate, float r, float g, float b ) +{ + BEAM *pbeam; + cl_entity_t *start, *end; + + start = R_BeamGetEntity( startEnt ); + end = R_BeamGetEntity( endEnt ); + + if( !start || !end ) + return NULL; + + if( life != 0 && ( !start->model || !end->model )) + return NULL; + + pbeam = R_BeamLightning( vec3_origin, vec3_origin, modelIndex, life, width, amplitude, brightness, speed ); + if( !pbeam ) return NULL; + + pbeam->type = TE_BEAMRING; + SetBits( pbeam->flags, FBEAM_STARTENTITY | FBEAM_ENDENTITY ); + if( life == 0 ) SetBits( pbeam->flags, FBEAM_FOREVER ); + pbeam->startEntity = startEnt; + pbeam->endEntity = endEnt; + + R_BeamSetAttributes( pbeam, r, g, b, framerate, startFrame ); + + return pbeam; +} + +/* +============== +R_BeamFollow + +Create beam following with entity +============== +*/ +BEAM *R_BeamFollow( int startEnt, int modelIndex, float life, float width, float r, float g, float b, float brightness ) +{ + BEAM *pbeam = R_BeamAlloc(); + + if( !pbeam ) return NULL; + pbeam->die = cl.time; + + if( modelIndex < 0 ) + return NULL; + + R_BeamSetup( pbeam, vec3_origin, vec3_origin, modelIndex, life, width, life, brightness, 1.0f ); + + pbeam->type = TE_BEAMFOLLOW; + SetBits( pbeam->flags, FBEAM_STARTENTITY ); + pbeam->startEntity = startEnt; + + R_BeamSetAttributes( pbeam, r, g, b, 1.0f, 0 ); + + return pbeam; +} + + +/* +============== +R_BeamLightning + +template for new beams +============== +*/ +BEAM *R_BeamLightning( vec3_t start, vec3_t end, int modelIndex, float life, float width, float amplitude, float brightness, float speed ) +{ + BEAM *pbeam = R_BeamAlloc(); + + if( !pbeam ) return NULL; + pbeam->die = cl.time; + + if( modelIndex < 0 ) + return NULL; + + R_BeamSetup( pbeam, start, end, modelIndex, life, width, amplitude, brightness, speed ); + + return pbeam; +} + + + +/* +=============== +R_EntityParticles + +set EF_BRIGHTFIELD effect +=============== +*/ +void R_EntityParticles( cl_entity_t *ent ) +{ + float angle; + float sr, sp, sy, cr, cp, cy; + vec3_t forward; + particle_t *p; + int i; + + for( i = 0; i < NUMVERTEXNORMALS; i++ ) + { + p = R_AllocParticle( NULL ); + if( !p ) return; + + angle = cl.time * cl_avelocities[i][0]; + SinCos( angle, &sy, &cy ); + angle = cl.time * cl_avelocities[i][1]; + SinCos( angle, &sp, &cp ); + angle = cl.time * cl_avelocities[i][2]; + SinCos( angle, &sr, &cr ); + + VectorSet( forward, cp * cy, cp * sy, -sp ); + + p->die = cl.time + 0.001f; + p->color = 111; // yellow + + VectorMAMAM( 1.0f, ent->origin, 64.0f, m_bytenormals[i], 16.0f, forward, p->org ); + } +} + +/* +=============== +R_ParticleExplosion + +=============== +*/ +void R_ParticleExplosion( const vec3_t org ) +{ + particle_t *p; + int i, j; + + for( i = 0; i < 1024; i++ ) + { + p = R_AllocParticle( NULL ); + if( !p ) return; + + p->die = cl.time + 5.0f; + p->ramp = COM_RandomLong( 0, 3 ); + p->color = ramp1[0]; + + for( j = 0; j < 3; j++ ) + { + p->org[j] = org[j] + COM_RandomFloat( -16.0f, 16.0f ); + p->vel[j] = COM_RandomFloat( -256.0f, 256.0f ); + } + + if( i & 1 ) p->type = pt_explode; + else p->type = pt_explode2; + } +} + +/* +=============== +R_ParticleExplosion2 + +=============== +*/ +void R_ParticleExplosion2( const vec3_t org, int colorStart, int colorLength ) +{ + int i, j; + int colorMod = 0; + particle_t *p; + + for( i = 0; i < 512; i++ ) + { + p = R_AllocParticle( NULL ); + if( !p ) return; + + p->die = cl.time + 0.3f; + p->color = colorStart + ( colorMod % colorLength ); + p->packedColor = 255; // use old code for blob particles + colorMod++; + + p->type = pt_blob; + + for( j = 0; j < 3; j++ ) + { + p->org[j] = org[j] + COM_RandomFloat( -16.0f, 16.0f ); + p->vel[j] = COM_RandomFloat( -256.0f, 256.0f ); + } + } +} + +/* +=============== +R_BlobExplosion + +=============== +*/ +void R_BlobExplosion( const vec3_t org ) +{ + particle_t *p; + int i, j; + + for( i = 0; i < 1024; i++ ) + { + p = R_AllocParticle( NULL ); + if( !p ) return; + + p->die = cl.time + COM_RandomFloat( 2.0f, 2.4f ); + p->packedColor = 255; // use old code for blob particles + + if( i & 1 ) + { + p->type = pt_blob; + p->color = COM_RandomLong( 66, 71 ); + } + else + { + p->type = pt_blob2; + p->color = COM_RandomLong( 150, 155 ); + } + + for( j = 0; j < 3; j++ ) + { + p->org[j] = org[j] + COM_RandomFloat( -16.0f, 16.0f ); + p->vel[j] = COM_RandomFloat( -256.0f, 256.0f ); + } + } +} + +/* +=============== +ParticleEffect + +PARTICLE_EFFECT on server +=============== +*/ +void R_RunParticleEffect( const vec3_t org, const vec3_t dir, int color, int count ) +{ + particle_t *p; + int i; + + if( count == 1024 ) + { + // rocket explosion + R_ParticleExplosion( org ); + return; + } + + for( i = 0; i < count; i++ ) + { + p = R_AllocParticle( NULL ); + if( !p ) return; + + p->color = (color & ~7) + COM_RandomLong( 0, 7 ); + p->die = cl.time + COM_RandomFloat( 0.1f, 0.4f ); + p->type = pt_slowgrav; + + VectorAddScalar( org, COM_RandomFloat( -8.0f, 8.0f ), p->org ); + VectorScale( dir, 15.0f, p->vel ); + } +} + +/* +=============== +R_Blood + +particle spray +=============== +*/ +void R_Blood( const vec3_t org, const vec3_t ndir, int pcolor, int speed ) +{ + vec3_t pos, dir, vec; + float pspeed = speed * 3.0f; + int i, j; + particle_t *p; + + VectorNormalize2( ndir, dir ); + + for( i = 0; i < (speed / 2); i++ ) + { + VectorAddScalar( org, COM_RandomFloat( -3.0f, 3.0f ), pos ); + VectorAddScalar( dir, COM_RandomFloat( -0.06f, 0.06f ), vec ); + + for( j = 0; j < 7; j++ ) + { + p = R_AllocParticle( NULL ); + if( !p ) return; + + p->die = cl.time + 1.5f; + p->color = pcolor + COM_RandomLong( 0, 9 ); + p->type = pt_vox_grav; + + VectorAddScalar( pos, COM_RandomFloat( -1.0f, 1.0f ), p->org ); + VectorScale( vec, pspeed, p->vel ); + } + } +} + +/* +=============== +R_BloodStream + +particle spray 2 +=============== +*/ +void R_BloodStream( const vec3_t org, const vec3_t dir, int pcolor, int speed ) +{ + particle_t *p; + int i, j; + float arc; + float accel = speed; + + for( arc = 0.05f, i = 0; i < 100; i++ ) + { + p = R_AllocParticle( NULL ); + if( !p ) return; + + p->die = cl.time + 2.0f; + p->type = pt_vox_grav; + p->color = pcolor + COM_RandomLong( 0, 9 ); + + VectorCopy( org, p->org ); + VectorCopy( dir, p->vel ); + + p->vel[2] -= arc; + arc -= 0.005f; + VectorScale( p->vel, accel, p->vel ); + accel -= 0.00001f; // so last few will drip + } + + for( arc = 0.075f, i = 0; i < ( speed / 5 ); i++ ) + { + float num; + + p = R_AllocParticle( NULL ); + if( !p ) return; + + p->die = cl.time + 3.0f; + p->color = pcolor + COM_RandomLong( 0, 9 ); + p->type = pt_vox_slowgrav; + + VectorCopy( org, p->org ); + VectorCopy( dir, p->vel ); + + p->vel[2] -= arc; + arc -= 0.005f; + + num = COM_RandomFloat( 0.0f, 1.0f ); + accel = speed * num; + num *= 1.7f; + + VectorScale( p->vel, num, p->vel ); + VectorScale( p->vel, accel, p->vel ); + + for( j = 0; j < 2; j++ ) + { + p = R_AllocParticle( NULL ); + if( !p ) return; + + p->die = cl.time + 3.0f; + p->color = pcolor + COM_RandomLong( 0, 9 ); + p->type = pt_vox_slowgrav; + + p->org[0] = org[0] + COM_RandomFloat( -1.0f, 1.0f ); + p->org[1] = org[1] + COM_RandomFloat( -1.0f, 1.0f ); + p->org[2] = org[2] + COM_RandomFloat( -1.0f, 1.0f ); + + VectorCopy( dir, p->vel ); + p->vel[2] -= arc; + + VectorScale( p->vel, num, p->vel ); + VectorScale( p->vel, accel, p->vel ); + } + } +} + +/* +=============== +R_LavaSplash + +=============== +*/ +void R_LavaSplash( const vec3_t org ) +{ + particle_t *p; + float vel; + vec3_t dir; + int i, j, k; + + for( i = -16; i < 16; i++ ) + { + for( j = -16; j <16; j++ ) + { + for( k = 0; k < 1; k++ ) + { + p = R_AllocParticle( NULL ); + if( !p ) return; + + p->die = cl.time + COM_RandomFloat( 2.0f, 2.62f ); + p->color = COM_RandomLong( 224, 231 ); + p->type = pt_slowgrav; + + dir[0] = j * 8.0f + COM_RandomFloat( 0.0f, 7.0f ); + dir[1] = i * 8.0f + COM_RandomFloat( 0.0f, 7.0f ); + dir[2] = 256.0f; + + p->org[0] = org[0] + dir[0]; + p->org[1] = org[1] + dir[1]; + p->org[2] = org[2] + COM_RandomFloat( 0.0f, 63.0f ); + + VectorNormalize( dir ); + vel = COM_RandomFloat( 50.0f, 113.0f ); + VectorScale( dir, vel, p->vel ); + } + } + } +} + +/* +=============== +R_ParticleBurst + +=============== +*/ +void R_ParticleBurst( const vec3_t org, int size, int color, float life ) +{ + particle_t *p; + vec3_t dir, dest; + int i, j; + float dist; + + for( i = 0; i < 32; i++ ) + { + for( j = 0; j < 32; j++ ) + { + p = R_AllocParticle( NULL ); + if( !p ) return; + + p->die = cl.time + life + COM_RandomFloat( -0.5f, 0.5f ); + p->color = color + COM_RandomLong( 0, 10 ); + p->ramp = 1.0f; + + VectorCopy( org, p->org ); + VectorAddScalar( org, COM_RandomFloat( -size, size ), dest ); + VectorSubtract( dest, p->org, dir ); + dist = VectorNormalizeLength( dir ); + VectorScale( dir, ( dist / life ), p->vel ); + } + } +} + +/* +=============== +R_LargeFunnel + +=============== +*/ +void R_LargeFunnel( const vec3_t org, int reverse ) +{ + particle_t *p; + float vel, dist; + vec3_t dir, dest; + int i, j; + + for( i = -8; i < 8; i++ ) + { + for( j = -8; j < 8; j++ ) + { + p = R_AllocParticle( NULL ); + if( !p ) return; + + dest[0] = (i * 32.0f) + org[0]; + dest[1] = (j * 32.0f) + org[1]; + dest[2] = org[2] + COM_RandomFloat( 100.0f, 800.0f ); + + if( reverse ) + { + VectorCopy( org, p->org ); + VectorSubtract( dest, p->org, dir ); + } + else + { + VectorCopy( dest, p->org ); + VectorSubtract( org, p->org, dir ); + } + + vel = dest[2] / 8.0f; + if( vel < 64.0f ) vel = 64.0f; + + dist = VectorNormalizeLength( dir ); + vel += COM_RandomFloat( 64.0f, 128.0f ); + VectorScale( dir, vel, p->vel ); + p->die = cl.time + (dist / vel ); + p->color = 244; // green color + } + } +} + +/* +=============== +R_TeleportSplash + +=============== +*/ +void R_TeleportSplash( const vec3_t org ) +{ + particle_t *p; + vec3_t dir; + float vel; + int i, j, k; + + for( i = -16; i < 16; i += 4 ) + { + for( j = -16; j < 16; j += 4 ) + { + for( k = -24; k < 32; k += 4 ) + { + p = R_AllocParticle( NULL ); + if( !p ) return; + + p->die = cl.time + COM_RandomFloat( 0.2f, 0.34f ); + p->color = COM_RandomLong( 7, 14 ); + p->type = pt_slowgrav; + + dir[0] = j * 8.0f; + dir[1] = i * 8.0f; + dir[2] = k * 8.0f; + + p->org[0] = org[0] + i + COM_RandomFloat( 0.0f, 3.0f ); + p->org[1] = org[1] + j + COM_RandomFloat( 0.0f, 3.0f ); + p->org[2] = org[2] + k + COM_RandomFloat( 0.0f, 3.0f ); + + VectorNormalize( dir ); + vel = COM_RandomFloat( 50.0f, 113.0f ); + VectorScale( dir, vel, p->vel ); + } + } + } +} + +/* +=============== +R_RocketTrail + +=============== +*/ +void R_RocketTrail( vec3_t start, vec3_t end, int type ) +{ + vec3_t vec, right, up; + static int tracercount; + float s, c, x, y; + float len, dec; + particle_t *p; + + VectorSubtract( end, start, vec ); + len = VectorNormalizeLength( vec ); + + if( type == 7 ) + { + VectorVectors( vec, right, up ); + } + + if( type < 128 ) + { + dec = 3.0f; + } + else + { + dec = 1.0f; + type -= 128; + } + + VectorScale( vec, dec, vec ); + + while( len > 0 ) + { + len -= dec; + + p = R_AllocParticle( NULL ); + if( !p ) return; + + p->die = cl.time + 2.0f; + + switch( type ) + { + case 0: // rocket trail + p->ramp = COM_RandomLong( 0, 3 ); + p->color = ramp3[(int)p->ramp]; + p->type = pt_fire; + VectorAddScalar( start, COM_RandomFloat( -3.0f, 3.0f ), p->org ); + break; + case 1: // smoke smoke + p->ramp = COM_RandomLong( 2, 5 ); + p->color = ramp3[(int)p->ramp]; + p->type = pt_fire; + VectorAddScalar( start, COM_RandomFloat( -3.0f, 3.0f ), p->org ); + break; + case 2: // blood + p->type = pt_grav; + p->color = COM_RandomLong( 67, 74 ); + VectorAddScalar( start, COM_RandomFloat( -3.0f, 3.0f ), p->org ); + break; + case 3: + case 5: // tracer + p->die = cl.time + 0.5f; + + if( type == 3 ) p->color = 52 + (( tracercount & 4 )<<1 ); + else p->color = 230 + (( tracercount & 4 )<<1 ); + + VectorCopy( start, p->org ); + tracercount++; + + if( FBitSet( tracercount, 1 )) + { + p->vel[0] = 30.0f * vec[1]; + p->vel[1] = 30.0f * -vec[0]; + } + else + { + p->vel[0] = 30.0f * -vec[1]; + p->vel[1] = 30.0f * vec[0]; + } + break; + case 4: // slight blood + p->type = pt_grav; + p->color = COM_RandomLong( 67, 70 ); + VectorAddScalar( start, COM_RandomFloat( -3.0f, 3.0f ), p->org ); + len -= 3.0f; + break; + case 6: // voor trail + p->color = COM_RandomLong( 152, 155 ); + p->die += 0.3f; + VectorAddScalar( start, COM_RandomFloat( -8.0f, 8.0f ), p->org ); + break; + case 7: // explosion tracer + x = COM_RandomLong( 0, 65535 ); + y = COM_RandomLong( 8, 16 ); + SinCos( x, &s, &c ); + s *= y; + c *= y; + + VectorMAMAM( 1.0f, start, s, right, c, up, p->org ); + VectorSubtract( start, p->org, p->vel ); + VectorScale( p->vel, 2.0f, p->vel ); + VectorMA( p->vel, COM_RandomFloat( 96.0f, 111.0f ), vec, p->vel ); + p->ramp = COM_RandomLong( 0, 3 ); + p->color = ramp3[(int)p->ramp]; + p->type = pt_explode2; + break; + default: + // just build line to show error + VectorCopy( start, p->org ); + break; + } + + VectorAdd( start, vec, start ); + } +} + +/* +================ +R_ParticleLine + +================ +*/ +void R_ParticleLine( const vec3_t start, const vec3_t end, byte r, byte g, byte b, float life ) +{ + int pcolor; + + pcolor = R_LookupColor( r, g, b ); + PM_ParticleLine( start, end, pcolor, life, 0 ); +} + +/* +================ +R_ParticleBox + +================ +*/ +void R_ParticleBox( const vec3_t absmin, const vec3_t absmax, byte r, byte g, byte b, float life ) +{ + vec3_t mins, maxs; + vec3_t origin; + int pcolor; + + pcolor = R_LookupColor( r, g, b ); + + VectorAverage( absmax, absmin, origin ); + VectorSubtract( absmax, origin, maxs ); + VectorSubtract( absmin, origin, mins ); + + PM_DrawBBox( mins, maxs, origin, pcolor, life ); +} + +/* +================ +R_ShowLine + +================ +*/ +void R_ShowLine( const vec3_t start, const vec3_t end ) +{ + vec3_t dir, org; + float len; + particle_t *p; + + VectorSubtract( end, start, dir ); + len = VectorNormalizeLength( dir ); + VectorScale( dir, 5.0f, dir ); + VectorCopy( start, org ); + + while( len > 0 ) + { + len -= 5.0f; + + p = R_AllocParticle( NULL ); + if( !p ) return; + + p->die = cl.time + 30; + p->color = 75; + + VectorCopy( org, p->org ); + VectorAdd( org, dir, org ); + } +} + +/* +=============== +R_BulletImpactParticles + +=============== +*/ +void R_BulletImpactParticles( const vec3_t pos ) +{ + int i, quantity; + int color; + float dist; + vec3_t dir; + particle_t *p; + + VectorSubtract( pos, refState.vieworg, dir ); + dist = VectorLength( dir ); + if( dist > 1000.0f ) dist = 1000.0f; + + quantity = (1000.0f - dist) / 100.0f; + if( quantity == 0 ) quantity = 1; + + color = 3 - ((30 * quantity) / 100 ); + R_SparkStreaks( pos, 2, -200, 200 ); + + for( i = 0; i < quantity * 4; i++ ) + { + p = R_AllocParticle( NULL ); + if( !p ) return; + + VectorCopy( pos, p->org); + + p->vel[0] = COM_RandomFloat( -1.0f, 1.0f ); + p->vel[1] = COM_RandomFloat( -1.0f, 1.0f ); + p->vel[2] = COM_RandomFloat( -1.0f, 1.0f ); + VectorScale( p->vel, COM_RandomFloat( 50.0f, 100.0f ), p->vel ); + + p->die = cl.time + 0.5; + p->color = 3 - color; + p->type = pt_grav; + } +} + +/* +=============== +R_FlickerParticles + +=============== +*/ +void R_FlickerParticles( const vec3_t org ) +{ + particle_t *p; + int i; + + for( i = 0; i < 15; i++ ) + { + p = R_AllocParticle( NULL ); + if( !p ) return; + + VectorCopy( org, p->org ); + p->vel[0] = COM_RandomFloat( -32.0f, 32.0f ); + p->vel[1] = COM_RandomFloat( -32.0f, 32.0f ); + p->vel[2] = COM_RandomFloat( 80.0f, 143.0f ); + + p->die = cl.time + 2.0f; + p->type = pt_blob2; + p->color = 254; + } +} + +/* +=============== +R_StreakSplash + +create a splash of streaks +=============== +*/ +void R_StreakSplash( const vec3_t pos, const vec3_t dir, int color, int count, float speed, int velocityMin, int velocityMax ) +{ + vec3_t vel, vel2; + particle_t *p; + int i; + + VectorScale( dir, speed, vel ); + + for( i = 0; i < count; i++ ) + { + VectorAddScalar( vel, COM_RandomFloat( velocityMin, velocityMax ), vel2 ); + p = R_AllocTracer( pos, vel2, COM_RandomFloat( 0.1f, 0.5f )); + if( !p ) return; + + p->type = pt_grav; + p->color = color; + p->ramp = 1.0f; + } +} + +/* +=============== +R_DebugParticle + +just for debug purposes +=============== +*/ +void R_DebugParticle( const vec3_t pos, byte r, byte g, byte b ) +{ + particle_t *p; + + p = R_AllocParticle( NULL ); + if( !p ) return; + + VectorCopy( pos, p->org ); + p->color = R_LookupColor( r, g, b ); + p->die = cl.time + 0.01f; +} + +/* +=============== +CL_Particle + +pmove debugging particle +=============== +*/ +void CL_Particle( const vec3_t org, int color, float life, int zpos, int zvel ) +{ + particle_t *p; + + p = R_AllocParticle( NULL ); + if( !p ) return; + + if( org ) VectorCopy( org, p->org ); + p->die = cl.time + life; + p->vel[2] += zvel; // ??? + p->color = color; +} + +/* +=============== +R_TracerEffect + +=============== +*/ +void R_TracerEffect( const vec3_t start, const vec3_t end ) +{ + vec3_t pos, vel, dir; + float len, speed; + float offset; + + speed = Q_max( tracerspeed->value, 3.0f ); + + VectorSubtract( end, start, dir ); + len = VectorLength( dir ); + if( len == 0.0f ) return; + + VectorScale( dir, 1.0f / len, dir ); // normalize + offset = COM_RandomFloat( -10.0f, 9.0f ) + traceroffset->value; + VectorScale( dir, offset, vel ); + VectorAdd( start, vel, pos ); + VectorScale( dir, speed, vel ); + + R_AllocTracer( pos, vel, len / speed ); +} + +/* +=============== +R_UserTracerParticle + +=============== +*/ +void R_UserTracerParticle( float *org, float *vel, float life, int colorIndex, float length, byte deathcontext, void (*deathfunc)( particle_t *p )) +{ + particle_t *p; + + if( colorIndex < 0 ) + return; + + if( colorIndex > ARRAYSIZE( gTracerColors )) + { + Con_Printf( S_ERROR "UserTracer with color > %d\n", ARRAYSIZE( gTracerColors )); + return; + } + + if(( p = R_AllocTracer( org, vel, life )) != NULL ) + { + p->context = deathcontext; + p->deathfunc = deathfunc; + p->color = colorIndex; + p->ramp = length; + } +} + +/* +=============== +R_TracerParticles + +allow more customization +=============== +*/ +particle_t *R_TracerParticles( float *org, float *vel, float life ) +{ + return R_AllocTracer( org, vel, life ); +} + +/* +=============== +R_SparkStreaks + +create a streak tracers +=============== +*/ +void R_SparkStreaks( const vec3_t pos, int count, int velocityMin, int velocityMax ) +{ + particle_t *p; + vec3_t vel; + int i; + + for( i = 0; icolor = 5; + p->type = pt_grav; + p->ramp = 0.5f; + } +} + +/* +=============== +R_Implosion + +make implosion tracers +=============== +*/ +void R_Implosion( const vec3_t end, float radius, int count, float life ) +{ + float dist = ( radius / 100.0f ); + vec3_t start, temp, vel; + float factor; + particle_t *p; + int i; + + if( life <= 0.0f ) life = 0.1f; // to avoid divide by zero + factor = -1.0 / life; + + for ( i = 0; i < count; i++ ) + { + temp[0] = dist * COM_RandomFloat( -100.0f, 100.0f ); + temp[1] = dist * COM_RandomFloat( -100.0f, 100.0f ); + temp[2] = dist * COM_RandomFloat( 0.0f, 100.0f ); + VectorScale( temp, factor, vel ); + VectorAdd( temp, end, start ); + + if(( p = R_AllocTracer( start, vel, life )) == NULL ) + return; + + p->type = pt_explode; + } +} + + +/* +============== +R_FreeDeadParticles + +Free particles that time has expired +============== +*/ +void R_FreeDeadParticles( particle_t **ppparticles ) +{ + particle_t *p, *kill; + + // kill all the ones hanging direcly off the base pointer + while( 1 ) + { + kill = *ppparticles; + if( kill && kill->die < cl.time ) + { + if( kill->deathfunc ) + kill->deathfunc( kill ); + kill->deathfunc = NULL; + *ppparticles = kill->next; + kill->next = cl_free_particles; + cl_free_particles = kill; + continue; + } + break; + } + + // kill off all the others + for( p = *ppparticles; p; p = p->next ) + { + while( 1 ) + { + kill = p->next; + if( kill && kill->die < cl.time ) + { + if( kill->deathfunc ) + kill->deathfunc( kill ); + kill->deathfunc = NULL; + p->next = kill->next; + kill->next = cl_free_particles; + cl_free_particles = kill; + continue; + } + break; + } + } +} + +/* +=============== +CL_ReadPointFile_f + +=============== +*/ +void CL_ReadPointFile_f( void ) +{ + char *afile, *pfile; + vec3_t org; + int count; + particle_t *p; + char filename[64]; + string token; + + Q_snprintf( filename, sizeof( filename ), "maps/%s.pts", clgame.mapname ); + afile = FS_LoadFile( filename, NULL, false ); + + if( !afile ) + { + Con_Printf( S_ERROR "couldn't open %s\n", filename ); + return; + } + + Con_Printf( "Reading %s...\n", filename ); + + count = 0; + pfile = afile; + + while( 1 ) + { + pfile = COM_ParseFile( pfile, token ); + if( !pfile ) break; + org[0] = Q_atof( token ); + + pfile = COM_ParseFile( pfile, token ); + if( !pfile ) break; + org[1] = Q_atof( token ); + + pfile = COM_ParseFile( pfile, token ); + if( !pfile ) break; + org[2] = Q_atof( token ); + + count++; + + if( !cl_free_particles ) + { + Con_Printf( S_ERROR "not enough free particles!\n" ); + break; + } + + // NOTE: can't use R_AllocParticle because this command + // may be executed from the console, while frametime is 0 + p = cl_free_particles; + cl_free_particles = p->next; + p->next = cl_active_particles; + cl_active_particles = p; + + p->ramp = 0; + p->type = pt_static; + p->die = cl.time + 99999; + p->color = (-count) & 15; + VectorCopy( org, p->org ); + VectorClear( p->vel ); + } + + Mem_Free( afile ); + + if( count ) Con_Printf( "%i points read\n", count ); + else Con_Printf( "map %s has no leaks!\n", clgame.mapname ); +} + + +void CL_FreeDeadBeams() +{ + BEAM *pBeam, *pNext, *pPrev = NULL; + // draw temporary entity beams + for( pBeam = cl_active_beams; pBeam; pBeam = pNext ) + { + // need to store the next one since we may delete this one + pNext = pBeam->next; + + // retire old beams + if( CL_BeamAttemptToDie( pBeam )) + { + // reset links + if( pPrev ) pPrev->next = pNext; + else cl_active_beams = pNext; + + // free the beam + R_BeamFree( pBeam ); + + pBeam = NULL; + continue; + } + + pPrev = pBeam; + } +} + + +void CL_DrawEFX( float time, qboolean fTrans ) +{ + CL_FreeDeadBeams(); + ref.dllFuncs.CL_DrawBeams( fTrans, cl_active_beams ); + + if( fTrans ) + { + R_FreeDeadParticles( &cl_active_particles ); + ref.dllFuncs.CL_DrawParticles( time, cl_active_particles ); + R_FreeDeadParticles( &cl_active_tracers ); + ref.dllFuncs.CL_DrawTracers( time, cl_active_tracers ); + } +} + diff --git a/engine/client/cl_frame.c b/engine/client/cl_frame.c index bf675485..7bc6fa89 100644 --- a/engine/client/cl_frame.c +++ b/engine/client/cl_frame.c @@ -965,7 +965,7 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType ) if( entityType == ET_BEAM ) { - CL_AddCustomBeam( ent ); + ref.dllFuncs.CL_AddCustomBeam( ent ); return true; } else if( !ref.dllFuncs.R_AddEntity( ent, entityType )) @@ -1299,7 +1299,7 @@ void CL_EmitEntities( void ) return; // animate lightestyles - CL_RunLightStyles (); + ref.dllFuncs.CL_RunLightStyles (); // decay dynamic lights CL_DecayLights (); diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index f1a9c50c..48d04205 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -3614,6 +3614,7 @@ triangleapi_t gTriApi; static efx_api_t gEfxApi = { +#if 1 R_AllocParticle, R_BlobExplosion, R_Blood, @@ -3688,6 +3689,7 @@ static efx_api_t gEfxApi = R_LookupColor, CL_DecalRemoveAll, CL_FireCustomDecal, +#endif }; static event_api_t gEventApi = @@ -4041,13 +4043,7 @@ qboolean CL_LoadProgs( const char *name ) // initialize game clgame.dllFuncs.pfnInit(); - CL_InitStudioAPI( ); - - // trying to grab them from client.dll - cl_righthand = Cvar_FindVar( "cl_righthand" ); - - if( cl_righthand == NULL ) - cl_righthand = Cvar_Get( "cl_righthand", "0", FCVAR_ARCHIVE, "flip viewmodel (left to right)" ); + ref.dllFuncs.CL_InitStudioAPI(); return true; } diff --git a/engine/client/cl_scrn.c b/engine/client/cl_scrn.c index d9150110..31b22770 100644 --- a/engine/client/cl_scrn.c +++ b/engine/client/cl_scrn.c @@ -730,7 +730,6 @@ void SCR_Init( void ) scr_viewsize = Cvar_Get( "viewsize", "120", FCVAR_ARCHIVE, "screen size" ); // register our commands - Cmd_AddCommand( "timerefresh", SCR_TimeRefresh_f, "turn quickly and print rendering statistcs" ); Cmd_AddCommand( "skyname", CL_SetSky_f, "set new skybox by basename" ); Cmd_AddCommand( "loadsky", CL_SetSky_f, "set new skybox by basename" ); Cmd_AddCommand( "viewpos", SCR_Viewpos_f, "prints current player origin" ); diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 60fdc61c..1806ddc8 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -2012,6 +2012,8 @@ void R_Sprite_WallPuff( TEMPENTITY *pTemp, float scale ) pTemp->die = cl.time + 0.01f; } + + /* ============== CL_ParseTempEntity @@ -3151,3 +3153,4 @@ void CL_ClearEffects( void ) CL_ClearParticles (); CL_ClearLightStyles (); } + diff --git a/engine/client/client.h b/engine/client/client.h index dad32413..8b40ea13 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -33,20 +33,6 @@ GNU General Public License for more details. #include "world.h" #include "ref_common.h" -#define MAX_DEMOS 32 -#define MAX_MOVIES 8 -#define MAX_CDTRACKS 32 -#define MAX_CLIENT_SPRITES 256 // SpriteTextures -#define MAX_EFRAGS 8192 // Arcane Dimensions required -#define MAX_REQUESTS 64 - -// screenshot types -#define VID_SCREENSHOT 0 -#define VID_LEVELSHOT 1 -#define VID_MINISHOT 2 -#define VID_MAPSHOT 3 // special case for overview layer -#define VID_SNAPSHOT 4 // save screenshot into root dir and no gamma correction - // client sprite types #define SPR_CLIENT 0 // client sprite for temp-entities or user-textures #define SPR_HUDSPRITE 1 // hud sprite @@ -167,13 +153,6 @@ typedef struct float weaponstarttime; } cl_local_data_t; -typedef struct -{ - char name[MAX_OSPATH]; - char modelname[MAX_OSPATH]; - model_t *model; -} player_model_t; - typedef struct { qboolean bUsed; @@ -238,7 +217,6 @@ typedef struct float timedelta; // floating delta between two updates char serverinfo[MAX_SERVERINFO_STRING]; - player_model_t player_models[MAX_CLIENTS]; // cache of player models player_info_t players[MAX_CLIENTS]; // collected info about all other players include himself double lastresourcecheck; string downloadUrl; @@ -1007,8 +985,6 @@ int CL_FxBlend( cl_entity_t *e ); void CL_InitParticles( void ); void CL_ClearParticles( void ); void CL_FreeParticles( void ); -void CL_DrawParticles( double frametime ); -void CL_DrawTracers( double frametime ); void CL_InitTempEnts( void ); void CL_ClearTempEnts( void ); void CL_FreeTempEnts( void ); @@ -1016,8 +992,6 @@ void CL_TempEntUpdate( void ); void CL_InitViewBeams( void ); void CL_ClearViewBeams( void ); void CL_FreeViewBeams( void ); -void CL_DrawBeams( int fTrans ); -void CL_AddCustomBeam( cl_entity_t *pEnvBeam ); void CL_KillDeadBeams( cl_entity_t *pDeadEntity ); void CL_ParseViewBeam( sizebuf_t *msg, int beamType ); void CL_LoadClientSprites( void ); diff --git a/engine/client/ref_common.c b/engine/client/ref_common.c index 30dbf8e3..fc5af332 100644 --- a/engine/client/ref_common.c +++ b/engine/client/ref_common.c @@ -8,10 +8,9 @@ ref_globals_t refState; convar_t *gl_vsync; convar_t *gl_showtextures; -convar_t *vid_displayfrequency; -convar_t *vid_fullscreen; convar_t *r_decals; convar_t *r_adjust_fov; +convar_t *gl_wgl_msaa_samples; void R_GetTextureParms( int *w, int *h, int texnum ) { @@ -19,12 +18,6 @@ void R_GetTextureParms( int *w, int *h, int texnum ) if( h ) *h = RENDER_GET_PARM( PARM_TEX_HEIGHT, texnum ); } -void VID_InitDefaultResolution( void ) -{ - refState.width = 640; - refState.height = 480; -} - /* ================ GL_FreeImage @@ -175,8 +168,6 @@ void R_Init( void ) gl_vsync = Cvar_Get( "gl_vsync", "0", FCVAR_ARCHIVE, "enable vertical syncronization" ); gl_showtextures = Cvar_Get( "gl_showtextures", "0", FCVAR_CHEAT, "show all uploaded textures" ); - vid_displayfrequency = Cvar_Get ( "vid_displayfrequency", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "fullscreen refresh rate" ); - vid_fullscreen = Cvar_Get( "fullscreen", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable fullscreen mode" ); r_adjust_fov = Cvar_Get( "r_adjust_fov", "1", FCVAR_ARCHIVE, "making FOV adjustment for wide-screens" ); r_decals = Cvar_Get( "r_decals", "4096", FCVAR_ARCHIVE, "sets the maximum number of decals" ); diff --git a/engine/client/ref_common.h b/engine/client/ref_common.h index 686af18d..97f78f7e 100644 --- a/engine/client/ref_common.h +++ b/engine/client/ref_common.h @@ -18,11 +18,6 @@ GNU General Public License for more details. #include "ref_api.h" -#define TF_SKY (TF_SKYSIDE|TF_NOMIPMAP) -#define TF_FONT (TF_NOMIPMAP|TF_CLAMP) -#define TF_IMAGE (TF_NOMIPMAP|TF_CLAMP) -#define TF_DECAL (TF_CLAMP) - #define RP_LOCALCLIENT( e ) ((e) != NULL && (e)->index == ( cl.playernum + 1 ) && e->player ) struct ref_state_s @@ -48,7 +43,7 @@ void R_GetTextureParms( int *w, int *h, int texnum ); extern convar_t *r_decals; extern convar_t *r_adjust_fov; -extern convar_t *vid_fullscreen; -extern convar_t *vid_displayfrequency; +void R_Init( void ); +void R_Shutdown( void ); #endif // REF_COMMON_H diff --git a/engine/client/vid_common.c b/engine/client/vid_common.c index ec3d63b3..2e537407 100644 --- a/engine/client/vid_common.c +++ b/engine/client/vid_common.c @@ -21,189 +21,18 @@ GNU General Public License for more details. #include "platform/platform.h" #define WINDOW_NAME XASH_ENGINE_NAME " Window" // Half-Life - -convar_t *gl_extensions; -convar_t *gl_texture_anisotropy; -convar_t *gl_texture_lodbias; -convar_t *gl_texture_nearest; -convar_t *gl_wgl_msaa_samples; -convar_t *gl_lightmap_nearest; -convar_t *gl_keeptjunctions; -convar_t *gl_emboss_scale; -convar_t *gl_detailscale; -convar_t *gl_check_errors; -convar_t *gl_polyoffset; -convar_t *gl_wireframe; -convar_t *gl_finish; -convar_t *gl_nosort; -convar_t *gl_vsync; -convar_t *gl_clear; -convar_t *gl_test; -convar_t *gl_msaa; -convar_t *gl_stencilbits; - -convar_t *window_xpos; -convar_t *window_ypos; -convar_t *r_speeds; -convar_t *r_fullbright; -convar_t *r_norefresh; -convar_t *r_showtree; -convar_t *r_lighting_extended; -convar_t *r_lighting_modulate; -convar_t *r_lighting_ambient; -convar_t *r_detailtextures; -convar_t *r_drawentities; -convar_t *r_adjust_fov; -convar_t *r_decals; -convar_t *r_novis; -convar_t *r_nocull; -convar_t *r_lockpvs; -convar_t *r_lockfrustum; -convar_t *r_traceglow; -convar_t *r_dynamic; -convar_t *r_lightmap; -convar_t *gl_round_down; -convar_t *r_vbo; -convar_t *r_vbo_dlightmode; - convar_t *vid_displayfrequency; convar_t *vid_fullscreen; convar_t *vid_brightness; convar_t *vid_gamma; convar_t *vid_highdpi; -byte *r_temppool; - -gl_globals_t tr; -glconfig_t glConfig; -glstate_t glState; +vidstate_t vidState; glwstate_t glw_state; +glcontext_t glContext; -/* -================= -GL_SetExtension -================= -*/ -void GL_SetExtension( int r_ext, int enable ) -{ - if( r_ext >= 0 && r_ext < GL_EXTCOUNT ) - glConfig.extension[r_ext] = enable ? GL_TRUE : GL_FALSE; - else Con_Printf( S_ERROR "GL_SetExtension: invalid extension %d\n", r_ext ); -} - -/* -================= -GL_Support -================= -*/ -qboolean GL_Support( int r_ext ) -{ - if( r_ext >= 0 && r_ext < GL_EXTCOUNT ) - return glConfig.extension[r_ext] ? true : false; - Con_Printf( S_ERROR "GL_Support: invalid extension %d\n", r_ext ); - - return false; -} - -/* -================= -GL_MaxTextureUnits -================= -*/ -int GL_MaxTextureUnits( void ) -{ - if( GL_Support( GL_SHADER_GLSL100_EXT )) - return Q_min( Q_max( glConfig.max_texture_coords, glConfig.max_teximage_units ), MAX_TEXTURE_UNITS ); - return glConfig.max_texture_units; -} - -/* -================= -GL_CheckExtension -================= -*/ -void GL_CheckExtension( const char *name, const dllfunc_t *funcs, const char *cvarname, int r_ext ) -{ - const dllfunc_t *func; - convar_t *parm = NULL; - const char *extensions_string; - - Con_Reportf( "GL_CheckExtension: %s ", name ); - GL_SetExtension( r_ext, true ); - - if( cvarname ) - { - // system config disable extensions - parm = Cvar_Get( cvarname, "1", FCVAR_GLCONFIG, va( CVAR_GLCONFIG_DESCRIPTION, name )); - } - - if(( parm && !CVAR_TO_BOOL( parm )) || ( !CVAR_TO_BOOL( gl_extensions ) && r_ext != GL_OPENGL_110 )) - { - Con_Reportf( "- disabled\n" ); - GL_SetExtension( r_ext, false ); - return; // nothing to process at - } - - extensions_string = glConfig.extensions_string; - - if(( name[2] == '_' || name[3] == '_' ) && !Q_strstr( extensions_string, name )) - { - GL_SetExtension( r_ext, false ); // update render info - Con_Reportf( "- ^1failed\n" ); - return; - } - - // clear exports - for( func = funcs; func && func->name; func++ ) - *func->func = NULL; - - for( func = funcs; func && func->name != NULL; func++ ) - { - // functions are cleared before all the extensions are evaluated - if((*func->func = (void *)GL_GetProcAddress( func->name )) == NULL ) - GL_SetExtension( r_ext, false ); // one or more functions are invalid, extension will be disabled - } - - if( GL_Support( r_ext )) - Con_Reportf( "- ^2enabled\n" ); - else Con_Reportf( "- ^1failed\n" ); -} - -/* -=============== -GL_SetDefaultTexState -=============== -*/ -static void GL_SetDefaultTexState( void ) -{ - int i; - - memset( glState.currentTextures, -1, MAX_TEXTURE_UNITS * sizeof( *glState.currentTextures )); - memset( glState.texCoordArrayMode, 0, MAX_TEXTURE_UNITS * sizeof( *glState.texCoordArrayMode )); - memset( glState.genSTEnabled, 0, MAX_TEXTURE_UNITS * sizeof( *glState.genSTEnabled )); - - for( i = 0; i < MAX_TEXTURE_UNITS; i++ ) - { - glState.currentTextureTargets[i] = GL_NONE; - glState.texIdentityMatrix[i] = true; - } -} - -/* -=============== -GL_SetDefaultState -=============== -*/ -static void GL_SetDefaultState( void ) -{ - memset( &glState, 0, sizeof( glState )); - GL_SetDefaultTexState (); - - // init draw stack - tr.draw_list = &tr.draw_stack[0]; - tr.draw_stack_pos = 0; -} - +convar_t *window_xpos; +convar_t *window_ypos; /* ================= VID_StartupGamma @@ -226,8 +55,8 @@ void VID_InitDefaultResolution( void ) { // we need to have something valid here // until video subsystem initialized - glState.width = 640; - glState.height = 480; + vidState.width = 640; + vidState.height = 480; } /* @@ -237,8 +66,8 @@ R_SaveVideoMode */ void R_SaveVideoMode( int w, int h ) { - glState.width = w; - glState.height = h; + vidState.width = w; + vidState.height = h; host.window_center_x = w / 2; host.window_center_y = h / 2; @@ -248,8 +77,8 @@ void R_SaveVideoMode( int w, int h ) // check for 4:3 or 5:4 if( w * 3 != h * 4 && w * 4 != h * 5 ) - glState.wideScreen = true; - else glState.wideScreen = false; + vidState.wideScreen = true; + else vidState.wideScreen = false; } /* @@ -280,7 +109,7 @@ void VID_CheckChanges( void ) { if( FBitSet( cl_allow_levelshots->flags, FCVAR_CHANGED )) { - GL_FreeTexture( cls.loadingBar ); + //GL_FreeTexture( cls.loadingBar ); SCR_RegisterTextures(); // reload 'lambda' image ClearBits( cl_allow_levelshots->flags, FCVAR_CHANGED ); } @@ -299,96 +128,6 @@ void VID_CheckChanges( void ) } } -/* -=============== -GL_SetDefaults -=============== -*/ -static void GL_SetDefaults( void ) -{ - pglFinish(); - - pglClearColor( 0.5f, 0.5f, 0.5f, 1.0f ); - - pglDisable( GL_DEPTH_TEST ); - pglDisable( GL_CULL_FACE ); - pglDisable( GL_SCISSOR_TEST ); - pglDepthFunc( GL_LEQUAL ); - pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); - - if( glState.stencilEnabled ) - { - pglDisable( GL_STENCIL_TEST ); - pglStencilMask( ( GLuint ) ~0 ); - pglStencilFunc( GL_EQUAL, 0, ~0 ); - pglStencilOp( GL_KEEP, GL_INCR, GL_INCR ); - } - - pglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - pglPolygonOffset( -1.0f, -2.0f ); - - GL_CleanupAllTextureUnits(); - - pglDisable( GL_BLEND ); - pglDisable( GL_ALPHA_TEST ); - pglDisable( GL_POLYGON_OFFSET_FILL ); - pglAlphaFunc( GL_GREATER, DEFAULT_ALPHATEST ); - pglEnable( GL_TEXTURE_2D ); - pglShadeModel( GL_SMOOTH ); - pglFrontFace( GL_CCW ); - - pglPointSize( 1.2f ); - pglLineWidth( 1.2f ); - - GL_Cull( GL_NONE ); -} - -/* -================= -R_RenderInfo_f -================= -*/ -void R_RenderInfo_f( void ) -{ - Con_Printf( "\n" ); - Con_Printf( "GL_VENDOR: %s\n", glConfig.vendor_string ); - Con_Printf( "GL_RENDERER: %s\n", glConfig.renderer_string ); - Con_Printf( "GL_VERSION: %s\n", glConfig.version_string ); - - // don't spam about extensions - if( host_developer.value >= DEV_EXTENDED ) - { - Con_Printf( "GL_EXTENSIONS: %s\n", glConfig.extensions_string ); - } - - Con_Printf( "GL_MAX_TEXTURE_SIZE: %i\n", glConfig.max_2d_texture_size ); - - if( GL_Support( GL_ARB_MULTITEXTURE )) - Con_Printf( "GL_MAX_TEXTURE_UNITS_ARB: %i\n", glConfig.max_texture_units ); - if( GL_Support( GL_TEXTURE_CUBEMAP_EXT )) - Con_Printf( "GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB: %i\n", glConfig.max_cubemap_size ); - if( GL_Support( GL_ANISOTROPY_EXT )) - Con_Printf( "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: %.1f\n", glConfig.max_texture_anisotropy ); - if( GL_Support( GL_TEXTURE_2D_RECT_EXT )) - Con_Printf( "GL_MAX_RECTANGLE_TEXTURE_SIZE: %i\n", glConfig.max_2d_rectangle_size ); - if( GL_Support( GL_TEXTURE_ARRAY_EXT )) - Con_Printf( "GL_MAX_ARRAY_TEXTURE_LAYERS_EXT: %i\n", glConfig.max_2d_texture_layers ); - if( GL_Support( GL_SHADER_GLSL100_EXT )) - { - Con_Printf( "GL_MAX_TEXTURE_COORDS_ARB: %i\n", glConfig.max_texture_coords ); - Con_Printf( "GL_MAX_TEXTURE_IMAGE_UNITS_ARB: %i\n", glConfig.max_teximage_units ); - Con_Printf( "GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB: %i\n", glConfig.max_vertex_uniforms ); - Con_Printf( "GL_MAX_VERTEX_ATTRIBS_ARB: %i\n", glConfig.max_vertex_attribs ); - } - - Con_Printf( "\n" ); - Con_Printf( "MODE: %ix%i\n", glState.width, glState.height ); - Con_Printf( "\n" ); - Con_Printf( "VERTICAL SYNC: %s\n", gl_vsync->value ? "enabled" : "disabled" ); - Con_Printf( "Color %d bits, Alpha %d bits, Depth %d bits, Stencil %d bits\n", glConfig.color_bits, - glConfig.alpha_bits, glConfig.depth_bits, glConfig.stencil_bits ); -} - static void VID_Mode_f( void ) { int w, h; @@ -424,86 +163,6 @@ static void VID_Mode_f( void ) R_ChangeDisplaySettings( w, h, Cvar_VariableInteger( "fullscreen" ) ); } -//======================================================================= - -/* -================= -GL_InitCommands -================= -*/ -void GL_InitCommands( void ) -{ - // system screen width and height (don't suppose for change from console at all) - Cvar_Get( "width", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen width" ); - Cvar_Get( "height", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen height" ); - r_speeds = Cvar_Get( "r_speeds", "0", FCVAR_ARCHIVE, "shows renderer speeds" ); - r_fullbright = Cvar_Get( "r_fullbright", "0", FCVAR_CHEAT, "disable lightmaps, get fullbright for entities" ); - r_norefresh = Cvar_Get( "r_norefresh", "0", 0, "disable 3D rendering (use with caution)" ); - r_showtree = Cvar_Get( "r_showtree", "0", FCVAR_ARCHIVE, "build the graph of visible BSP tree" ); - r_lighting_extended = Cvar_Get( "r_lighting_extended", "1", FCVAR_ARCHIVE, "allow to get lighting from world and bmodels" ); - r_lighting_modulate = Cvar_Get( "r_lighting_modulate", "0.6", FCVAR_ARCHIVE, "lightstyles modulate scale" ); - r_lighting_ambient = Cvar_Get( "r_lighting_ambient", "0.3", FCVAR_ARCHIVE, "map ambient lighting scale" ); - r_novis = Cvar_Get( "r_novis", "0", 0, "ignore vis information (perfomance test)" ); - r_nocull = Cvar_Get( "r_nocull", "0", 0, "ignore frustrum culling (perfomance test)" ); - r_detailtextures = Cvar_Get( "r_detailtextures", "1", FCVAR_ARCHIVE, "enable detail textures support, use '2' for autogenerate detail.txt" ); - r_lockpvs = Cvar_Get( "r_lockpvs", "0", FCVAR_CHEAT, "lockpvs area at current point (pvs test)" ); - r_lockfrustum = Cvar_Get( "r_lockfrustum", "0", FCVAR_CHEAT, "lock frustrum area at current point (cull test)" ); - r_dynamic = Cvar_Get( "r_dynamic", "1", FCVAR_ARCHIVE, "allow dynamic lighting (dlights, lightstyles)" ); - r_traceglow = Cvar_Get( "r_traceglow", "1", FCVAR_ARCHIVE, "cull flares behind models" ); - r_lightmap = Cvar_Get( "r_lightmap", "0", FCVAR_CHEAT, "lightmap debugging tool" ); - r_drawentities = Cvar_Get( "r_drawentities", "1", FCVAR_CHEAT, "render entities" ); - r_decals = engine.Cvar_Find( "r_decals" ); - window_xpos = Cvar_Get( "_window_xpos", "130", FCVAR_RENDERINFO, "window position by horizontal" ); - window_ypos = Cvar_Get( "_window_ypos", "48", FCVAR_RENDERINFO, "window position by vertical" ); - - gl_extensions = Cvar_Get( "gl_allow_extensions", "1", FCVAR_GLCONFIG, "allow gl_extensions" ); - gl_texture_nearest = Cvar_Get( "gl_texture_nearest", "0", FCVAR_ARCHIVE, "disable texture filter" ); - gl_lightmap_nearest = Cvar_Get( "gl_lightmap_nearest", "0", FCVAR_ARCHIVE, "disable lightmap filter" ); - gl_check_errors = Cvar_Get( "gl_check_errors", "1", FCVAR_ARCHIVE, "ignore video engine errors" ); - gl_vsync = engine.Cvar_Find( "gl_vsync" ); - gl_detailscale = Cvar_Get( "gl_detailscale", "4.0", FCVAR_ARCHIVE, "default scale applies while auto-generate list of detail textures" ); - gl_texture_anisotropy = Cvar_Get( "gl_anisotropy", "8", FCVAR_ARCHIVE, "textures anisotropic filter" ); - gl_texture_lodbias = Cvar_Get( "gl_texture_lodbias", "0.0", FCVAR_ARCHIVE, "LOD bias for mipmapped textures (perfomance|quality)" ); - gl_keeptjunctions = Cvar_Get( "gl_keeptjunctions", "1", FCVAR_ARCHIVE, "removing tjuncs causes blinking pixels" ); - gl_emboss_scale = Cvar_Get( "gl_emboss_scale", "0", FCVAR_ARCHIVE|FCVAR_LATCH, "fake bumpmapping scale" ); - gl_showtextures = engine.Cvar_Find( "r_showtextures" ); - gl_finish = Cvar_Get( "gl_finish", "0", FCVAR_ARCHIVE, "use glFinish instead of glFlush" ); - gl_nosort = Cvar_Get( "gl_nosort", "0", FCVAR_ARCHIVE, "disable sorting of translucent surfaces" ); - gl_clear = Cvar_Get( "gl_clear", "0", FCVAR_ARCHIVE, "clearing screen after each frame" ); - gl_test = Cvar_Get( "gl_test", "0", 0, "engine developer cvar for quick testing new features" ); - gl_wireframe = Cvar_Get( "gl_wireframe", "0", FCVAR_ARCHIVE|FCVAR_SPONLY, "show wireframe overlay" ); - gl_wgl_msaa_samples = Cvar_Get( "gl_wgl_msaa_samples", "0", FCVAR_GLCONFIG, "samples number for multisample anti-aliasing" ); - gl_msaa = Cvar_Get( "gl_msaa", "1", FCVAR_ARCHIVE, "enable or disable multisample anti-aliasing" ); - gl_stencilbits = Cvar_Get( "gl_stencilbits", "8", FCVAR_GLCONFIG, "pixelformat stencil bits (0 - auto)" ); - gl_round_down = Cvar_Get( "gl_round_down", "2", FCVAR_RENDERINFO, "round texture sizes to nearest POT value" ); - // these cvar not used by engine but some mods requires this - gl_polyoffset = Cvar_Get( "gl_polyoffset", "2.0", FCVAR_ARCHIVE, "polygon offset for decals" ); - - // make sure gl_vsync is checked after vid_restart - SetBits( gl_vsync->flags, FCVAR_CHANGED ); - - vid_gamma = Cvar_Get( "gamma", "2.5", FCVAR_ARCHIVE, "gamma amount" ); - vid_brightness = Cvar_Get( "brightness", "0.0", FCVAR_ARCHIVE, "brightness factor" ); - vid_fullscreen = engine.Cvar_Find( "fullscreen" ); - vid_displayfrequency = engine.Cvar_Find ( "vid_displayfrequency" ); - vid_highdpi = Cvar_Get( "vid_highdpi", "1", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable High-DPI mode" ); - - Cmd_AddCommand( "r_info", R_RenderInfo_f, "display renderer info" ); - - // a1ba: planned to be named vid_mode for compability - // but supported mode list is filled by backends, so numbers are not portable any more - Cmd_AddCommand( "vid_setmode", VID_Mode_f, "display video mode" ); - - // give initial OpenGL configuration - host.apply_opengl_config = true; - Cbuf_AddText( "exec opengl.cfg\n" ); - Cbuf_Execute(); - host.apply_opengl_config = false; - - // apply actual video mode to window - Cbuf_AddText( "exec video.cfg\n" ); - Cbuf_Execute(); -} /* ================= @@ -545,171 +204,8 @@ static void SetFullscreenModeFromCommandLine( ) #endif } - -/* -=============== -R_CheckVBO - -register VBO cvars and get default value -=============== -*/ -static void R_CheckVBO( void ) -{ - const char *def = "1"; - const char *dlightmode = "1"; - int flags = FCVAR_ARCHIVE; - qboolean disable = false; - - // some bad GLES1 implementations breaks dlights completely - if( glConfig.max_texture_units < 3 ) - disable = true; - -#ifdef XASH_MOBILE_PLATFORM - // VideoCore4 drivers have a problem with mixing VBO and client arrays - // Disable it, as there is no suitable workaround here - if( Q_stristr( glConfig.renderer_string, "VideoCore IV" ) || Q_stristr( glConfig.renderer_string, "vc4" ) ) - disable = true; - - // dlightmode 1 is not too much tested on android - // so better to left it off - dlightmode = "0"; -#endif - - if( disable ) - { - // do not keep in config unless dev > 3 and enabled - flags = 0; - def = "0"; - } - - r_vbo = Cvar_Get( "r_vbo", def, flags, "draw world using VBO" ); - r_vbo_dlightmode = Cvar_Get( "r_vbo_dlightmode", dlightmode, FCVAR_ARCHIVE, "vbo dlight rendering mode(0-1)" ); - - // check if enabled manually - if( CVAR_TO_BOOL(r_vbo) ) - r_vbo->flags |= FCVAR_ARCHIVE; -} - -/* -=============== -R_Init -=============== -*/ -qboolean R_Init( void ) -{ - if( glw_state.initialized ) - return true; - - GL_InitCommands(); - GL_InitRandomTable(); - - // Set screen resolution and fullscreen mode if passed in on command line. - // This is done after executing opengl.cfg, as the command line values should take priority. - SetWidthAndHeightFromCommandLine(); - SetFullscreenModeFromCommandLine(); - - GL_SetDefaultState(); - - // create the window and set up the context - if( !R_Init_Video( )) - { - GL_RemoveCommands(); - R_Free_Video(); - - Sys_Error( "Can't initialize video subsystem\nProbably driver was not installed" ); - return false; - } - - host.renderinfo_changed = false; - r_temppool = Mem_AllocPool( "Render Zone" ); - - GL_SetDefaults(); - R_CheckVBO(); - R_InitImages(); - R_SpriteInit(); - R_StudioInit(); - R_AliasInit(); - R_ClearDecals(); - R_ClearScene(); - - // initialize screen - SCR_Init(); - - return true; -} - -/* -=============== -R_Shutdown -=============== -*/ -void R_Shutdown( void ) -{ - model_t *mod; - int i; - - if( !glw_state.initialized ) - return; - - // release SpriteTextures - for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ ) - { - if( !mod->name[0] ) continue; - Mod_UnloadSpriteModel( mod ); - } - memset( clgame.sprites, 0, sizeof( clgame.sprites )); - - GL_RemoveCommands(); - R_ShutdownImages(); - - Mem_FreePool( &r_temppool ); - - // shut down OS specific OpenGL stuff like contexts, etc. - R_Free_Video(); -} - -/* -================= -GL_ErrorString -convert errorcode to string -================= -*/ -const char *GL_ErrorString( int err ) -{ - switch( err ) - { - case GL_STACK_OVERFLOW: - return "GL_STACK_OVERFLOW"; - case GL_STACK_UNDERFLOW: - return "GL_STACK_UNDERFLOW"; - case GL_INVALID_ENUM: - return "GL_INVALID_ENUM"; - case GL_INVALID_VALUE: - return "GL_INVALID_VALUE"; - case GL_INVALID_OPERATION: - return "GL_INVALID_OPERATION"; - case GL_OUT_OF_MEMORY: - return "GL_OUT_OF_MEMORY"; - default: - return "UNKNOWN ERROR"; - } -} - -/* -================= -GL_CheckForErrors -obsolete -================= -*/ -void GL_CheckForErrors_( const char *filename, const int fileline ) +void VID_Init() { - int err; - - if( !CVAR_TO_BOOL( gl_check_errors )) - return; - - if(( err = pglGetError( )) == GL_NO_ERROR ) - return; - - Con_Printf( S_OPENGL_ERROR "%s (called at %s:%i)\n", GL_ErrorString( err ), filename, fileline ); + vid_displayfrequency = Cvar_Get ( "vid_displayfrequency", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "fullscreen refresh rate" ); + vid_fullscreen = Cvar_Get( "fullscreen", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable fullscreen mode" ); } diff --git a/engine/client/vid_common.h b/engine/client/vid_common.h index 329776ea..9134e63d 100644 --- a/engine/client/vid_common.h +++ b/engine/client/vid_common.h @@ -4,7 +4,7 @@ #define FCONTEXT_CORE_PROFILE BIT( 0 ) #define FCONTEXT_DEBUG_ARB BIT( 1 ) - +#if 0 #define GL_CheckForErrors() GL_CheckForErrors_( __FILE__, __LINE__ ) void GL_CheckForErrors_( const char *filename, const int fileline ); const char *GL_ErrorString( int err ); @@ -13,5 +13,81 @@ qboolean GL_Support( int r_ext ); int GL_MaxTextureUnits( void ); void GL_CheckExtension( const char *name, const dllfunc_t *funcs, const char *cvarname, int r_ext ); void GL_SetExtension( int r_ext, int enable ); +#endif + +typedef struct vidmode_s +{ + const char *desc; + int width; + int height; +} vidmode_t; + + +typedef enum +{ + SAFE_NO = 0, + SAFE_NOMSAA, // skip msaa + SAFE_NOACC, // don't set acceleration flag + SAFE_NOSTENCIL, // don't set stencil bits + SAFE_NOALPHA, // don't set alpha bits + SAFE_NODEPTH, // don't set depth bits + SAFE_NOCOLOR, // don't set color bits + SAFE_DONTCARE // ignore everything, let SDL/EGL decide +} safe_context_t; + + +typedef struct +{ + void* context; // handle to GL rendering context + int safe; + + int desktopBitsPixel; + int desktopWidth; + int desktopHeight; + + qboolean initialized; // OpenGL subsystem started + qboolean extended; // extended context allows to GL_Debug +} glwstate_t; + + +typedef struct vidstate_s +{ + int width, height; + int prev_width, prev_height; + qboolean fullScreen; + qboolean wideScreen; +} vidstate_t; + +// engine will manage opengl contexts with window system (egl/sdl or wgl/glx if needed) +typedef struct glcontext_s +{ + /// make renderapi defs acessible here? +// gl_context_type_t context; +// gles_wrapper_t wrapper; + int color_bits; + int alpha_bits; + int depth_bits; + int stencil_bits; + int msaasamples; + + int max_multisamples; +} glcontext_t; + +extern vidstate_t vidState; +extern glwstate_t glw_state; +extern glcontext_t glContext; + + +#define VID_MIN_HEIGHT 200 +#define VID_MIN_WIDTH 320 + +extern convar_t *vid_fullscreen; +extern convar_t *vid_displayfrequency; +extern convar_t *vid_highdpi; +extern convar_t *gl_wgl_msaa_samples; +void R_SaveVideoMode( int w, int h ); +void VID_CheckChanges( void ); +const char *VID_GetModeString( int vid_mode ); +void VID_StartupGamma( void ); #endif // VID_COMMON diff --git a/engine/common/common.h b/engine/common/common.h index 7778fc96..8057515d 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -84,80 +84,6 @@ XASH SPECIFIC - sort of hack that works only in Xash3D not in GoldSrc #define HACKS_RELATED_HLMODS // some HL-mods works differently under Xash and can't be fixed without some hacks at least at current time -#define MAX_STRING 256 // generic string -#define MAX_INFO_STRING 256 // infostrings are transmitted across network -#define MAX_SERVERINFO_STRING 512 // server handles too many settings. expand to 1024? -#define MAX_LOCALINFO_STRING 32768 // localinfo used on server and not sended to the clients -#define MAX_SYSPATH 1024 // system filepath -#define MAX_PRINT_MSG 8192 // how many symbols can handle single call of Con_Printf or Con_DPrintf -#define MAX_TOKEN 2048 // parse token length -#define MAX_MODS 512 // environment games that engine can keep visible -#define MAX_USERMSG_LENGTH 2048 // don't modify it's relies on a client-side definitions - -#define BIT( n ) ( 1 << ( n )) -#define GAMMA ( 2.2 ) // Valve Software gamma -#define INVGAMMA ( 1.0 / 2.2 ) // back to 1.0 -#define TEXGAMMA ( 0.9 ) // compensate dim textures -#define SetBits( iBitVector, bits ) ((iBitVector) = (iBitVector) | (bits)) -#define ClearBits( iBitVector, bits ) ((iBitVector) = (iBitVector) & ~(bits)) -#define FBitSet( iBitVector, bit ) ((iBitVector) & (bit)) - -#ifndef __cplusplus -#ifdef NULL -#undef NULL -#endif - -#define NULL ((void *)0) -#endif - -// color strings -#define IsColorString( p ) ( p && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' ) -#define ColorIndex( c ) ((( c ) - '0' ) & 7 ) - -#if defined __i386__ && defined __GNUC__ -#define GAME_EXPORT __attribute__((force_align_arg_pointer)) -#else -#define GAME_EXPORT -#endif - - -#ifdef XASH_BIG_ENDIAN -#define LittleLong(x) (((int)(((x)&255)<<24)) + ((int)((((x)>>8)&255)<<16)) + ((int)(((x)>>16)&255)<<8) + (((x) >> 24)&255)) -#define LittleLongSW(x) (x = LittleLong(x) ) -#define LittleShort(x) ((short)( (((short)(x) >> 8) & 255) + (((short)(x) & 255) << 8))) -#define LittleShortSW(x) (x = LittleShort(x) ) -_inline float LittleFloat( float f ) -{ - union - { - float f; - unsigned char b[4]; - } dat1, dat2; - - dat1.f = f; - dat2.b[0] = dat1.b[3]; - dat2.b[1] = dat1.b[2]; - dat2.b[2] = dat1.b[1]; - dat2.b[3] = dat1.b[0]; - - return dat2.f; -} -#else -#define LittleLong(x) (x) -#define LittleLongSW(x) -#define LittleShort(x) (x) -#define LittleShortSW(x) -#define LittleFloat(x) (x) -#endif - - -typedef unsigned int dword; -typedef unsigned int uint; -typedef char string[MAX_STRING]; -typedef struct file_s file_t; // normal file -typedef struct wfile_s wfile_t; // wad file -typedef struct stream_s stream_t; // sound stream for background music playing -typedef off_t fs_offset_t; typedef void (*setpair_t)( const char *key, const char *value, void *buffer, void *numpairs ); @@ -610,117 +536,11 @@ int FS_Close( file_t *file ); int FS_Getc( file_t *file ); fs_offset_t FS_FileLength( file_t *f ); -/* -======================================================================== - -internal image format - -typically expanded to rgba buffer -NOTE: number at end of pixelformat name it's a total bitscount e.g. PF_RGB_24 == PF_RGB_888 -======================================================================== -*/ -#define ImageRAW( type ) (type == PF_RGBA_32 || type == PF_BGRA_32 || type == PF_RGB_24 || type == PF_BGR_24) -#define ImageDXT( type ) (type == PF_DXT1 || type == PF_DXT3 || type == PF_DXT5 || type == PF_ATI2) - -typedef enum -{ - PF_UNKNOWN = 0, - PF_INDEXED_24, // inflated palette (768 bytes) - PF_INDEXED_32, // deflated palette (1024 bytes) - PF_RGBA_32, // normal rgba buffer - PF_BGRA_32, // big endian RGBA (MacOS) - PF_RGB_24, // uncompressed dds or another 24-bit image - PF_BGR_24, // big-endian RGB (MacOS) - PF_DXT1, // s3tc DXT1 format - PF_DXT3, // s3tc DXT3 format - PF_DXT5, // s3tc DXT5 format - PF_ATI2, // latc ATI2N format - PF_TOTALCOUNT, // must be last -} pixformat_t; - -typedef struct bpc_desc_s -{ - int format; // pixelformat - char name[16]; // used for debug - uint glFormat; // RGBA format - int bpp; // channels (e.g. rgb = 3, rgba = 4) -} bpc_desc_t; - -// imagelib global settings -typedef enum -{ - IL_USE_LERPING = BIT(0), // lerping images during resample - IL_KEEP_8BIT = BIT(1), // don't expand paletted images - IL_ALLOW_OVERWRITE = BIT(2), // allow to overwrite stored images - IL_DONTFLIP_TGA = BIT(3), // Steam background completely ignore tga attribute 0x20 (stupid lammers!) - IL_DDS_HARDWARE = BIT(4), // DXT compression is support - IL_LOAD_DECAL = BIT(5), // special mode for load gradient decals - IL_OVERVIEW = BIT(6), // overview required some unque operations -} ilFlags_t; - -// goes into rgbdata_t->encode -#define DXT_ENCODE_DEFAULT 0 // don't use custom encoders -#define DXT_ENCODE_COLOR_YCoCg 0x1A01 // make sure that value dosn't collide with anything -#define DXT_ENCODE_ALPHA_1BIT 0x1A02 // normal 1-bit alpha -#define DXT_ENCODE_ALPHA_8BIT 0x1A03 // normal 8-bit alpha -#define DXT_ENCODE_ALPHA_SDF 0x1A04 // signed distance field -#define DXT_ENCODE_NORMAL_AG_ORTHO 0x1A05 // orthographic projection -#define DXT_ENCODE_NORMAL_AG_STEREO 0x1A06 // stereographic projection -#define DXT_ENCODE_NORMAL_AG_PARABOLOID 0x1A07 // paraboloid projection -#define DXT_ENCODE_NORMAL_AG_QUARTIC 0x1A08 // newton method -#define DXT_ENCODE_NORMAL_AG_AZIMUTHAL 0x1A09 // Lambert Azimuthal Equal-Area - -// rgbdata output flags -typedef enum -{ - // rgbdata->flags - IMAGE_CUBEMAP = BIT(0), // it's 6-sides cubemap buffer - IMAGE_HAS_ALPHA = BIT(1), // image contain alpha-channel - IMAGE_HAS_COLOR = BIT(2), // image contain RGB-channel - IMAGE_COLORINDEX = BIT(3), // all colors in palette is gradients of last color (decals) - IMAGE_HAS_LUMA = BIT(4), // image has luma pixels (q1-style maps) - IMAGE_SKYBOX = BIT(5), // only used by FS_SaveImage - for write right suffixes - IMAGE_QUAKESKY = BIT(6), // it's a quake sky double layered clouds (so keep it as 8 bit) - IMAGE_DDS_FORMAT = BIT(7), // a hint for GL loader - IMAGE_MULTILAYER = BIT(8), // to differentiate from 3D texture - IMAGE_ONEBIT_ALPHA = BIT(9), // binary alpha - IMAGE_QUAKEPAL = BIT(10), // image has quake1 palette - - // Image_Process manipulation flags - IMAGE_FLIP_X = BIT(16), // flip the image by width - IMAGE_FLIP_Y = BIT(17), // flip the image by height - IMAGE_ROT_90 = BIT(18), // flip from upper left corner to down right corner - IMAGE_ROT180 = IMAGE_FLIP_X|IMAGE_FLIP_Y, - IMAGE_ROT270 = IMAGE_FLIP_X|IMAGE_FLIP_Y|IMAGE_ROT_90, - IMAGE_EMBOSS = BIT(19), // apply emboss mapping - IMAGE_RESAMPLE = BIT(20), // resample image to specified dims -// reserved -// reserved - IMAGE_FORCE_RGBA = BIT(23), // force image to RGBA buffer - IMAGE_MAKE_LUMA = BIT(24), // create luma texture from indexed - IMAGE_QUANTIZE = BIT(25), // make indexed image from 24 or 32- bit image - IMAGE_LIGHTGAMMA = BIT(26), // apply gamma for image - IMAGE_REMAP = BIT(27), // interpret width and height as top and bottom color -} imgFlags_t; - -typedef struct rgbdata_s -{ - word width; // image width - word height; // image height - word depth; // image depth - uint type; // compression type - uint flags; // misc image flags - word encode; // DXT may have custom encoder, that will be decoded in GLSL-side - byte numMips; // mipmap count - byte *palette; // palette if present - byte *buffer; // image buffer - rgba_t fogParams; // some water textures in hl1 has info about fog color and alpha - size_t size; // for bounds checking -} rgbdata_t; - // // imagelib // +#include "com_image.h" + void Image_Init( void ); void Image_Shutdown( void ); void Image_AddCmdFlags( uint flags ); @@ -738,7 +558,6 @@ qboolean Image_CustomPalette( void ); void Image_ClearForceFlags( void ); void Image_SetMDLPointer( byte *p ); void Image_CheckPaletteQ1( void ); - /* ======================================================================== diff --git a/engine/common/mod_local.h b/engine/common/mod_local.h index ed3f39de..84bba470 100644 --- a/engine/common/mod_local.h +++ b/engine/common/mod_local.h @@ -20,25 +20,6 @@ GNU General Public License for more details. #include "edict.h" #include "eiface.h" -// 1/32 epsilon to keep floating point happy -#define DIST_EPSILON (1.0f / 32.0f) -#define FRAC_EPSILON (1.0f / 1024.0f) -#define BACKFACE_EPSILON 0.01f -#define MAX_BOX_LEAFS 256 -#define ANIM_CYCLE 2 -#define MOD_FRAMES 20 - -// remapping info -#define SUIT_HUE_START 192 -#define SUIT_HUE_END 223 -#define PLATE_HUE_START 160 -#define PLATE_HUE_END 191 - -#define SHIRT_HUE_START 16 -#define SHIRT_HUE_END 32 -#define PANTS_HUE_START 96 -#define PANTS_HUE_END 112 - #define LM_SAMPLE_SIZE 16 #define LM_SAMPLE_EXTRASIZE 8 diff --git a/engine/common/system.h b/engine/common/system.h index 87e42903..2a9853ae 100644 --- a/engine/common/system.h +++ b/engine/common/system.h @@ -63,19 +63,6 @@ NOTE: never change this structure because all dll descriptions in xash code writes into struct by offsets not names ======================================================================== */ -typedef struct dllfunc_s -{ - const char *name; - void **func; -} dllfunc_t; - -typedef struct dll_info_s -{ - const char *name; // name of library - const dllfunc_t *fcts; // list of dll exports - qboolean crash; // crash if dll not found - void *link; // hinstance of loading library -} dll_info_t; void Sys_Sleep( int msec ); double Sys_DoubleTime( void ); diff --git a/engine/platform/sdl/vid_sdl.c b/engine/platform/sdl/vid_sdl.c index 4d0b78d4..968f0e65 100644 --- a/engine/platform/sdl/vid_sdl.c +++ b/engine/platform/sdl/vid_sdl.c @@ -245,14 +245,15 @@ qboolean GL_CreateContext( void ) SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &colorBits[0] ); SDL_GL_GetAttribute( SDL_GL_GREEN_SIZE, &colorBits[1] ); SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, &colorBits[2] ); - glConfig.color_bits = colorBits[0] + colorBits[1] + colorBits[2]; + glContext.color_bits = colorBits[0] + colorBits[1] + colorBits[2]; - SDL_GL_GetAttribute( SDL_GL_ALPHA_SIZE, &glConfig.alpha_bits ); - SDL_GL_GetAttribute( SDL_GL_DEPTH_SIZE, &glConfig.depth_bits ); - SDL_GL_GetAttribute( SDL_GL_STENCIL_SIZE, &glConfig.stencil_bits ); - glState.stencilEnabled = glConfig.stencil_bits ? true : false; + SDL_GL_GetAttribute( SDL_GL_ALPHA_SIZE, &glContext.alpha_bits ); + SDL_GL_GetAttribute( SDL_GL_DEPTH_SIZE, &glContext.depth_bits ); + SDL_GL_GetAttribute( SDL_GL_STENCIL_SIZE, &glContext.stencil_bits ); + /// move to ref + //vidState.stencilEnabled = glContext.stencil_bits ? true : false; - SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &glConfig.msaasamples ); + SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &glContext.msaasamples ); #ifdef XASH_WES void wes_init(); @@ -491,9 +492,9 @@ void VID_DestroyWindow( void ) host.hWnd = NULL; } - if( glState.fullScreen ) + if( vidState.fullScreen ) { - glState.fullScreen = false; + vidState.fullScreen = false; } } @@ -563,8 +564,9 @@ static void GL_SetupAttributes( void ) Msg( "bpp %d\n", glw_state.desktopBitsPixel ); - if( glw_state.safe < SAFE_NOSTENCIL ) - SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, gl_stencilbits->value ); + /// ref context attribs api +// if( glw_state.safe < SAFE_NOSTENCIL ) +// SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, gl_stencilbits->value ); if( glw_state.safe < SAFE_NOALPHA ) SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 ); @@ -615,14 +617,14 @@ static void GL_SetupAttributes( void ) SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 ); SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, samples ); - glConfig.max_multisamples = samples; + glContext.max_multisamples = samples; } else { SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 0 ); SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, 0 ); - glConfig.max_multisamples = 0; + glContext.max_multisamples = 0; } } else @@ -674,7 +676,7 @@ qboolean R_Init_Video( void ) return retval; } - GL_InitExtensions(); + ref.dllFuncs.GL_InitExtensions(); return true; } @@ -692,7 +694,7 @@ rserr_t R_ChangeDisplaySettings( int width, int height, qboolean fullscreen ) glw_state.desktopWidth = displayMode.w; glw_state.desktopHeight = displayMode.h; - glState.fullScreen = fullscreen; + vidState.fullScreen = fullscreen; if( !host.hWnd ) { @@ -764,8 +766,8 @@ qboolean VID_SetMode( void ) if(( err = R_ChangeDisplaySettings( iScreenWidth, iScreenHeight, fullscreen )) == rserr_ok ) { - glConfig.prev_width = iScreenWidth; - glConfig.prev_height = iScreenHeight; + vidState.prev_width = iScreenWidth; + vidState.prev_height = iScreenHeight; } else { @@ -784,7 +786,7 @@ qboolean VID_SetMode( void ) } // try setting it back to something safe - if(( err = R_ChangeDisplaySettings( glConfig.prev_width, glConfig.prev_height, false )) != rserr_ok ) + if(( err = R_ChangeDisplaySettings( vidState.prev_width, vidState.prev_height, false )) != rserr_ok ) { Con_Reportf( S_ERROR "VID_SetMode: could not revert to safe mode\n" ); Sys_Warn("could not revert to safe mode!"); diff --git a/ref_gl/gl_alias.c b/ref_gl/gl_alias.c index 6226c90b..7127daa0 100644 --- a/ref_gl/gl_alias.c +++ b/ref_gl/gl_alias.c @@ -12,16 +12,13 @@ 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. */ - -#include "common.h" -#include "client.h" +#include "gl_local.h" #include "mathlib.h" #include "const.h" #include "r_studioint.h" #include "triangleapi.h" #include "alias.h" #include "pm_local.h" -#include "gl_local.h" #include "cl_tent.h" extern cvar_t r_shadows; diff --git a/ref_gl/gl_backend.c b/ref_gl/gl_backend.c index 99963bb1..0c3c1b9d 100644 --- a/ref_gl/gl_backend.c +++ b/ref_gl/gl_backend.c @@ -13,8 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" -#include "client.h" + #include "gl_local.h" #include "mathlib.h" @@ -85,7 +84,7 @@ void GL_BackendEndFrame( void ) return; if( !RI.viewleaf ) - curleaf = cl.worldmodel->leafs; + curleaf = WORLDMODEL->leafs; else curleaf = RI.viewleaf; R_Speeds_Printf( "Renderer: ^1Engine^7\n\n" ); @@ -97,7 +96,7 @@ void GL_BackendEndFrame( void ) r_stats.c_world_polys, r_stats.c_alias_polys, r_stats.c_studio_polys, r_stats.c_sprite_polys ); break; case 2: - R_Speeds_Printf( "visible leafs:\n%3i leafs\ncurrent leaf %3i\n", r_stats.c_world_leafs, curleaf - cl.worldmodel->leafs ); + R_Speeds_Printf( "visible leafs:\n%3i leafs\ncurrent leaf %3i\n", r_stats.c_world_leafs, curleaf - WORLDMODEL->leafs ); R_Speeds_Printf( "ReciusiveWorldNode: %3lf secs\nDrawTextureChains %lf\n", r_stats.t_world_node, r_stats.t_world_draw ); break; case 3: @@ -560,7 +559,7 @@ qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qbo string basename; int i = 1, flags, result; - if( !RI.drawWorld || !cl.worldmodel ) + if( !RI.drawWorld || !WORLDMODEL ) return false; // make sure the specified size is valid @@ -786,7 +785,7 @@ void R_ShowTree_r( mnode_t *node, float x, float y, float scale, int shownodes ) if( shownodes == 1 ) { - if( cl.worldmodel->leafs == leaf ) + if( WORLDMODEL->leafs == leaf ) pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); else if( RI.viewleaf && RI.viewleaf == leaf ) pglColor4f( 1.0f, 0.0f, 0.0f, 1.0f ); @@ -819,7 +818,7 @@ void R_ShowTree( void ) float x = (float)((glState.width - (int)POINT_SIZE) >> 1); float y = NODE_INTERVAL_Y(1.0); - if( !cl.worldmodel || !CVAR_TO_BOOL( r_showtree )) + if( !WORLDMODEL || !CVAR_TO_BOOL( r_showtree )) return; tr.recursion_level = 0; @@ -831,11 +830,11 @@ void R_ShowTree( void ) pglLineWidth( 2.0f ); pglColor3f( 1, 0.7f, 0 ); pglDisable( GL_TEXTURE_2D ); - R_ShowTree_r( cl.worldmodel->nodes, x, y, tr.max_recursion * 3.5f, 2 ); + R_ShowTree_r( WORLDMODEL->nodes, x, y, tr.max_recursion * 3.5f, 2 ); pglEnable( GL_TEXTURE_2D ); pglLineWidth( 1.0f ); - R_ShowTree_r( cl.worldmodel->nodes, x, y, tr.max_recursion * 3.5f, 1 ); + R_ShowTree_r( WORLDMODEL->nodes, x, y, tr.max_recursion * 3.5f, 1 ); Con_NPrintf( 0, "max recursion %d\n", tr.max_recursion ); } @@ -874,10 +873,10 @@ void SCR_TimeRefresh_f( void ) { for( i = 0; i < 128; i++ ) { - ref.dllFuncs.R_BeginFrame( true ); + R_BeginFrame( true ); refState.viewangles[1] = i / 128.0 * 360.0f; - ref.dllFuncs.R_RenderScene(); - ref.dllFuncs.R_EndFrame(); + R_RenderScene(); + R_EndFrame(); } } diff --git a/ref_gl/gl_beams.c b/ref_gl/gl_beams.c index ff2a1f14..60e2ea1e 100644 --- a/ref_gl/gl_beams.c +++ b/ref_gl/gl_beams.c @@ -13,8 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" -#include "client.h" +#include "gl_local.h" #include "r_efx.h" #include "event_flags.h" #include "entity_types.h" @@ -22,7 +21,7 @@ GNU General Public License for more details. #include "customentity.h" #include "cl_tent.h" #include "pm_local.h" -#include "gl_local.h" + #include "studio.h" #define NOISE_DIVISIONS 64 // don't touch - many tripmines cause the crash when it equal 128 @@ -75,6 +74,7 @@ static void SineNoise( float *noise, int divs ) } } + /* ============================================================== @@ -108,230 +108,6 @@ static void R_BeamComputeNormal( const vec3_t vStartPos, const vec3_t vNextPos, VectorNormalizeFast( pNormal ); } -/* -============================================================== - -BEAM ALLOCATE & PROCESSING - -============================================================== -*/ -/* -============== -R_BeamAlloc - -============== -*/ -BEAM *R_BeamAlloc( void ) -{ - BEAM *pBeam; - - if( !cl_free_beams ) - return NULL; - - pBeam = cl_free_beams; - cl_free_beams = pBeam->next; - memset( pBeam, 0, sizeof( *pBeam )); - pBeam->next = cl_active_beams; - cl_active_beams = pBeam; - pBeam->die = cl.time; - - return pBeam; -} - -/* -============== -R_BeamFree - -============== -*/ -void R_BeamFree( BEAM *pBeam ) -{ - // free particles that have died off. - R_FreeDeadParticles( &pBeam->particles ); - - // now link into free list; - pBeam->next = cl_free_beams; - cl_free_beams = pBeam; -} - -/* -============== -R_BeamSetup - -generic function. all beams must be -passed through this -============== -*/ -void R_BeamSetup( BEAM *pbeam, vec3_t start, vec3_t end, int modelIndex, float life, float width, float amplitude, float brightness, float speed ) -{ - model_t *sprite = CL_ModelHandle( modelIndex ); - - if( !sprite ) return; - - pbeam->type = BEAM_POINTS; - pbeam->modelIndex = modelIndex; - pbeam->frame = 0; - pbeam->frameRate = 0; - pbeam->frameCount = sprite->numframes; - - VectorCopy( start, pbeam->source ); - VectorCopy( end, pbeam->target ); - VectorSubtract( end, start, pbeam->delta ); - - pbeam->freq = speed * cl.time; - pbeam->die = life + cl.time; - pbeam->amplitude = amplitude; - pbeam->brightness = brightness; - pbeam->width = width; - pbeam->speed = speed; - - if( amplitude >= 0.50f ) - pbeam->segments = VectorLength( pbeam->delta ) * 0.25f + 3.0f; // one per 4 pixels - else pbeam->segments = VectorLength( pbeam->delta ) * 0.075f + 3.0f; // one per 16 pixels - - pbeam->pFollowModel = NULL; - pbeam->flags = 0; -} - -/* -============== -R_BeamSetAttributes - -set beam attributes -============== -*/ -void R_BeamSetAttributes( BEAM *pbeam, float r, float g, float b, float framerate, int startFrame ) -{ - pbeam->frame = (float)startFrame; - pbeam->frameRate = framerate; - pbeam->r = r; - pbeam->g = g; - pbeam->b = b; -} - -/* -============== -R_BeamLightning - -template for new beams -============== -*/ -BEAM *R_BeamLightning( vec3_t start, vec3_t end, int modelIndex, float life, float width, float amplitude, float brightness, float speed ) -{ - BEAM *pbeam = R_BeamAlloc(); - - if( !pbeam ) return NULL; - pbeam->die = cl.time; - - if( modelIndex < 0 ) - return NULL; - - R_BeamSetup( pbeam, start, end, modelIndex, life, width, amplitude, brightness, speed ); - - return pbeam; -} - -/* -============== -R_BeamGetEntity - -extract entity number from index -handle user entities -============== -*/ -static cl_entity_t *R_BeamGetEntity( int index ) -{ - if( index < 0 ) - return clgame.dllFuncs.pfnGetUserEntity( BEAMENT_ENTITY( -index )); - return CL_GetEntityByIndex( BEAMENT_ENTITY( index )); -} - -/* -============== -R_BeamComputePoint - -compute attachment point for beam -============== -*/ -static qboolean R_BeamComputePoint( int beamEnt, vec3_t pt ) -{ - cl_entity_t *ent; - int attach; - - ent = R_BeamGetEntity( beamEnt ); - - if( beamEnt < 0 ) - attach = BEAMENT_ATTACHMENT( -beamEnt ); - else attach = BEAMENT_ATTACHMENT( beamEnt ); - - if( !ent ) - { - Con_DPrintf( S_ERROR "R_BeamComputePoint: invalid entity %i\n", BEAMENT_ENTITY( beamEnt )); - VectorClear( pt ); - return false; - } - - // get attachment - if( attach > 0 ) - VectorCopy( ent->attachment[attach - 1], pt ); - else if(( ent->index - 1 ) == cl.playernum ) - VectorCopy( cl.simorg, pt ); - else VectorCopy( ent->origin, pt ); - - return true; -} - -/* -============== -R_BeamRecomputeEndpoints - -Recomputes beam endpoints.. -============== -*/ -qboolean R_BeamRecomputeEndpoints( BEAM *pbeam ) -{ - if( FBitSet( pbeam->flags, FBEAM_STARTENTITY )) - { - cl_entity_t *start = R_BeamGetEntity( pbeam->startEntity ); - - if( R_BeamComputePoint( pbeam->startEntity, pbeam->source )) - { - if( !pbeam->pFollowModel ) - pbeam->pFollowModel = start->model; - SetBits( pbeam->flags, FBEAM_STARTVISIBLE ); - } - else if( !FBitSet( pbeam->flags, FBEAM_FOREVER )) - { - ClearBits( pbeam->flags, FBEAM_STARTENTITY ); - } - } - - if( FBitSet( pbeam->flags, FBEAM_ENDENTITY )) - { - cl_entity_t *end = R_BeamGetEntity( pbeam->endEntity ); - - if( R_BeamComputePoint( pbeam->endEntity, pbeam->target )) - { - if( !pbeam->pFollowModel ) - pbeam->pFollowModel = end->model; - SetBits( pbeam->flags, FBEAM_ENDVISIBLE ); - } - else if( !FBitSet( pbeam->flags, FBEAM_FOREVER )) - { - ClearBits( pbeam->flags, FBEAM_ENDENTITY ); - pbeam->die = cl.time; - return false; - } - else - { - return false; - } - } - - if( FBitSet( pbeam->flags, FBEAM_STARTENTITY ) && !FBitSet( pbeam->flags, FBEAM_STARTVISIBLE )) - return false; - return true; -} /* ============== @@ -357,7 +133,7 @@ qboolean R_BeamCull( const vec3_t start, const vec3_t end, qboolean pvsOnly ) mins[i] = end[i]; maxs[i] = start[i]; } - + // don't let it be zero sized if( mins[i] == maxs[i] ) maxs[i] += 1.0f; @@ -369,7 +145,7 @@ qboolean R_BeamCull( const vec3_t start, const vec3_t end, qboolean pvsOnly ) if( pvsOnly || !R_CullBox( mins, maxs )) { // beam is visible - return false; + return false; } } @@ -377,6 +153,29 @@ qboolean R_BeamCull( const vec3_t start, const vec3_t end, qboolean pvsOnly ) return true; } +/* +================ +CL_AddCustomBeam + +Add the beam that encoded as custom entity +================ +*/ +void CL_AddCustomBeam( cl_entity_t *pEnvBeam ) +{ + if( tr.draw_list->num_beam_entities >= MAX_VISIBLE_PACKET ) + { + Con_Printf( S_ERROR "Too many beams %d!\n", tr.draw_list->num_beam_entities ); + return; + } + + if( pEnvBeam ) + { + tr.draw_list->beam_entities[tr.draw_list->num_beam_entities] = pEnvBeam; + tr.draw_list->num_beam_entities++; + } +} + + /* ============================================================== @@ -975,7 +774,7 @@ void R_DrawRing( vec3_t source, vec3_t delta, float width, float amplitude, floa VectorAdd( center, last1, tmp ); // maxs VectorSubtract( center, last1, screen ); // mins - if( !cl.worldmodel ) + if( !WORLDMODEL ) return; // is that box in PVS && frustum? @@ -1045,32 +844,137 @@ void R_DrawRing( vec3_t source, vec3_t delta, float width, float amplitude, floa } } +/// export from engine... /* ============== -R_BeamDraw +R_BeamGetEntity -Update beam vars and draw it +extract entity number from index +handle user entities ============== */ -void R_BeamDraw( BEAM *pbeam, float frametime ) +static cl_entity_t *R_BeamGetEntity( int index ) { - model_t *model; - vec3_t delta; + if( index < 0 ) + return clgame.dllFuncs.pfnGetUserEntity( BEAMENT_ENTITY( -index )); + return CL_GetEntityByIndex( BEAMENT_ENTITY( index )); +} - model = CL_ModelHandle( pbeam->modelIndex ); - SetBits( pbeam->flags, FBEAM_ISACTIVE ); - if( !model || model->type != mod_sprite ) - { - pbeam->flags &= ~FBEAM_ISACTIVE; // force to ignore - pbeam->die = cl.time; - return; - } +/* +============== +R_BeamComputePoint - // update frequency - pbeam->freq += frametime; +compute attachment point for beam +============== +*/ +static qboolean R_BeamComputePoint( int beamEnt, vec3_t pt ) +{ + cl_entity_t *ent; + int attach; - // generate fractal noise + ent = R_BeamGetEntity( beamEnt ); + + if( beamEnt < 0 ) + attach = BEAMENT_ATTACHMENT( -beamEnt ); + else attach = BEAMENT_ATTACHMENT( beamEnt ); + + if( !ent ) + { + Con_DPrintf( S_ERROR "R_BeamComputePoint: invalid entity %i\n", BEAMENT_ENTITY( beamEnt )); + VectorClear( pt ); + return false; + } + + // get attachment + if( attach > 0 ) + VectorCopy( ent->attachment[attach - 1], pt ); + else if(( ent->index - 1 ) == cl.playernum ) + VectorCopy( cl.simorg, pt ); + else VectorCopy( ent->origin, pt ); + + return true; +} + +/* +============== +R_BeamRecomputeEndpoints + +Recomputes beam endpoints.. +============== +*/ +qboolean R_BeamRecomputeEndpoints( BEAM *pbeam ) +{ + if( FBitSet( pbeam->flags, FBEAM_STARTENTITY )) + { + cl_entity_t *start = R_BeamGetEntity( pbeam->startEntity ); + + if( R_BeamComputePoint( pbeam->startEntity, pbeam->source )) + { + if( !pbeam->pFollowModel ) + pbeam->pFollowModel = start->model; + SetBits( pbeam->flags, FBEAM_STARTVISIBLE ); + } + else if( !FBitSet( pbeam->flags, FBEAM_FOREVER )) + { + ClearBits( pbeam->flags, FBEAM_STARTENTITY ); + } + } + + if( FBitSet( pbeam->flags, FBEAM_ENDENTITY )) + { + cl_entity_t *end = R_BeamGetEntity( pbeam->endEntity ); + + if( R_BeamComputePoint( pbeam->endEntity, pbeam->target )) + { + if( !pbeam->pFollowModel ) + pbeam->pFollowModel = end->model; + SetBits( pbeam->flags, FBEAM_ENDVISIBLE ); + } + else if( !FBitSet( pbeam->flags, FBEAM_FOREVER )) + { + ClearBits( pbeam->flags, FBEAM_ENDENTITY ); + pbeam->die = cl.time; + return false; + } + else + { + return false; + } + } + + if( FBitSet( pbeam->flags, FBEAM_STARTENTITY ) && !FBitSet( pbeam->flags, FBEAM_STARTVISIBLE )) + return false; + return true; +} + + +/* +============== +R_BeamDraw + +Update beam vars and draw it +============== +*/ +void R_BeamDraw( BEAM *pbeam, float frametime ) +{ + model_t *model; + vec3_t delta; + + model = CL_ModelHandle( pbeam->modelIndex ); + SetBits( pbeam->flags, FBEAM_ISACTIVE ); + + if( !model || model->type != mod_sprite ) + { + pbeam->flags &= ~FBEAM_ISACTIVE; // force to ignore + pbeam->die = cl.time; + return; + } + + // update frequency + pbeam->freq += frametime; + + // generate fractal noise if( frametime != 0.0f ) { rgNoise[0] = 0; @@ -1231,8 +1135,66 @@ void R_BeamDraw( BEAM *pbeam, float frametime ) } GL_Cull( GL_FRONT ); + r_stats.c_view_beams_count++; } +/* +============== +R_BeamSetAttributes + +set beam attributes +============== +*/ +static void R_BeamSetAttributes( BEAM *pbeam, float r, float g, float b, float framerate, int startFrame ) +{ + pbeam->frame = (float)startFrame; + pbeam->frameRate = framerate; + pbeam->r = r; + pbeam->g = g; + pbeam->b = b; +} + +/* +============== +R_BeamSetup + +generic function. all beams must be +passed through this +============== +*/ +static void R_BeamSetup( BEAM *pbeam, vec3_t start, vec3_t end, int modelIndex, float life, float width, float amplitude, float brightness, float speed ) +{ + model_t *sprite = CL_ModelHandle( modelIndex ); + + if( !sprite ) return; + + pbeam->type = BEAM_POINTS; + pbeam->modelIndex = modelIndex; + pbeam->frame = 0; + pbeam->frameRate = 0; + pbeam->frameCount = sprite->numframes; + + VectorCopy( start, pbeam->source ); + VectorCopy( end, pbeam->target ); + VectorSubtract( end, start, pbeam->delta ); + + pbeam->freq = speed * cl.time; + pbeam->die = life + cl.time; + pbeam->amplitude = amplitude; + pbeam->brightness = brightness; + pbeam->width = width; + pbeam->speed = speed; + + if( amplitude >= 0.50f ) + pbeam->segments = VectorLength( pbeam->delta ) * 0.25f + 3.0f; // one per 4 pixels + else pbeam->segments = VectorLength( pbeam->delta ) * 0.075f + 3.0f; // one per 16 pixels + + pbeam->pFollowModel = NULL; + pbeam->flags = 0; +} + + + /* ============== R_BeamDrawCustomEntity @@ -1303,175 +1265,6 @@ void R_BeamDrawCustomEntity( cl_entity_t *ent ) R_BeamDraw( &beam, tr.frametime ); } -/* -============================================================== - -VIEWBEAMS MANAGEMENT - -============================================================== -*/ -BEAM *cl_active_beams; -BEAM *cl_free_beams; -BEAM *cl_viewbeams = NULL; // beams pool - -/* -================ -CL_InitViewBeams - -================ -*/ -void CL_InitViewBeams( void ) -{ - cl_viewbeams = Mem_Calloc( cls.mempool, sizeof( BEAM ) * GI->max_beams ); - CL_ClearViewBeams(); -} - -/* -================ -CL_ClearViewBeams - -================ -*/ -void CL_ClearViewBeams( void ) -{ - int i; - - if( !cl_viewbeams ) return; - - // clear beams - cl_free_beams = cl_viewbeams; - cl_active_beams = NULL; - - for( i = 0; i < GI->max_beams - 1; i++ ) - cl_viewbeams[i].next = &cl_viewbeams[i+1]; - cl_viewbeams[GI->max_beams - 1].next = NULL; -} - -/* -================ -CL_FreeViewBeams - -================ -*/ -void CL_FreeViewBeams( void ) -{ - if( cl_viewbeams ) - Mem_Free( cl_viewbeams ); - cl_viewbeams = NULL; -} - -/* -================ -CL_AddCustomBeam - -Add the beam that encoded as custom entity -================ -*/ -void CL_AddCustomBeam( cl_entity_t *pEnvBeam ) -{ - if( tr.draw_list->num_beam_entities >= MAX_VISIBLE_PACKET ) - { - Con_Printf( S_ERROR "Too many beams %d!\n", tr.draw_list->num_beam_entities ); - return; - } - - if( pEnvBeam ) - { - tr.draw_list->beam_entities[tr.draw_list->num_beam_entities] = pEnvBeam; - tr.draw_list->num_beam_entities++; - } -} - - -/* -============== -CL_KillDeadBeams - -============== -*/ -void CL_KillDeadBeams( cl_entity_t *pDeadEntity ) -{ - BEAM *pbeam; - BEAM *pnewlist; - BEAM *pnext; - particle_t *pHead; // build a new list to replace cl_active_beams. - - pbeam = cl_active_beams; // old list. - pnewlist = NULL; // new list. - - while( pbeam ) - { - pnext = pbeam->next; - - // link into new list. - if( R_BeamGetEntity( pbeam->startEntity ) != pDeadEntity ) - { - pbeam->next = pnewlist; - pnewlist = pbeam; - - pbeam = pnext; - continue; - } - - pbeam->flags &= ~(FBEAM_STARTENTITY | FBEAM_ENDENTITY); - - if( pbeam->type != TE_BEAMFOLLOW ) - { - // remove beam - pbeam->die = cl.time - 0.1f; - - // kill off particles - pHead = pbeam->particles; - while( pHead ) - { - pHead->die = cl.time - 0.1f; - pHead = pHead->next; - } - - // free the beam - R_BeamFree( pbeam ); - } - else - { - // stay active - pbeam->next = pnewlist; - pnewlist = pbeam; - } - - pbeam = pnext; - } - - // We now have a new list with the bogus stuff released. - cl_active_beams = pnewlist; -} - -/* -============== -CL_BeamAttemptToDie - -Check for expired beams -============== -*/ -qboolean CL_BeamAttemptToDie( BEAM *pBeam ) -{ - Assert( pBeam != NULL ); - - // premanent beams never die automatically - if( FBitSet( pBeam->flags, FBEAM_FOREVER )) - return false; - - if( pBeam->type == TE_BEAMFOLLOW && pBeam->particles ) - { - // wait for all trails are dead - return false; - } - - // other beams - if( pBeam->die > cl.time ) - return false; - - return true; -} /* ============== @@ -1480,7 +1273,7 @@ CL_DrawBeams draw beam loop ============== */ -void CL_DrawBeams( int fTrans ) +void CL_DrawBeams(int fTrans , BEAM *active_beams ) { BEAM *pBeam, *pNext; BEAM *pPrev = NULL; @@ -1512,508 +1305,17 @@ void CL_DrawBeams( int fTrans ) RI.currentbeam = NULL; // draw temporary entity beams - for( pBeam = cl_active_beams; pBeam; pBeam = pNext ) + for( pBeam = active_beams; pBeam; pBeam = pBeam->next ) { - // need to store the next one since we may delete this one - pNext = pBeam->next; - if( fTrans && FBitSet( pBeam->flags, FBEAM_SOLID )) continue; if( !fTrans && !FBitSet( pBeam->flags, FBEAM_SOLID )) continue; - // retire old beams - if( CL_BeamAttemptToDie( pBeam )) - { - // reset links - if( pPrev ) pPrev->next = pNext; - else cl_active_beams = pNext; - - // free the beam - R_BeamFree( pBeam ); - - pBeam = NULL; - continue; - } - R_BeamDraw( pBeam, cl.time - cl.oldtime ); - r_stats.c_view_beams_count++; - pPrev = pBeam; } pglShadeModel( GL_FLAT ); pglDepthMask( GL_TRUE ); } - -/* -============== -R_BeamKill - -Remove beam attached to specified entity -and all particle trails (if this is a beamfollow) -============== -*/ -void R_BeamKill( int deadEntity ) -{ - cl_entity_t *pDeadEntity; - - pDeadEntity = R_BeamGetEntity( deadEntity ); - if( !pDeadEntity ) return; - - CL_KillDeadBeams( pDeadEntity ); -} - -/* -============== -R_BeamEnts - -Create beam between two ents -============== -*/ -BEAM *R_BeamEnts( int startEnt, int endEnt, int modelIndex, float life, float width, float amplitude, float brightness, - float speed, int startFrame, float framerate, float r, float g, float b ) -{ - cl_entity_t *start, *end; - BEAM *pbeam; - model_t *mod; - - mod = CL_ModelHandle( modelIndex ); - - // need a valid model. - if( !mod || mod->type != mod_sprite ) - return NULL; - - start = R_BeamGetEntity( startEnt ); - end = R_BeamGetEntity( endEnt ); - - if( !start || !end ) - return NULL; - - // don't start temporary beams out of the PVS - if( life != 0 && ( !start->model || !end->model )) - return NULL; - - pbeam = R_BeamLightning( vec3_origin, vec3_origin, modelIndex, life, width, amplitude, brightness, speed ); - if( !pbeam ) return NULL; - - pbeam->type = TE_BEAMPOINTS; - SetBits( pbeam->flags, FBEAM_STARTENTITY | FBEAM_ENDENTITY ); - if( life == 0 ) SetBits( pbeam->flags, FBEAM_FOREVER ); - - pbeam->startEntity = startEnt; - pbeam->endEntity = endEnt; - - R_BeamSetAttributes( pbeam, r, g, b, framerate, startFrame ); - - return pbeam; -} - -/* -============== -R_BeamPoints - -Create beam between two points -============== -*/ -BEAM *R_BeamPoints( vec3_t start, vec3_t end, int modelIndex, float life, float width, float amplitude, - float brightness, float speed, int startFrame, float framerate, float r, float g, float b ) -{ - BEAM *pbeam; - - if( life != 0 && R_BeamCull( start, end, true )) - return NULL; - - pbeam = R_BeamAlloc(); - if( !pbeam ) return NULL; - - pbeam->die = cl.time; - - if( modelIndex < 0 ) - return NULL; - - R_BeamSetup( pbeam, start, end, modelIndex, life, width, amplitude, brightness, speed ); - if( life == 0 ) SetBits( pbeam->flags, FBEAM_FOREVER ); - - R_BeamSetAttributes( pbeam, r, g, b, framerate, startFrame ); - - return pbeam; -} - -/* -============== -R_BeamCirclePoints - -Create beam cicrle -============== -*/ -BEAM *R_BeamCirclePoints( int type, vec3_t start, vec3_t end, int modelIndex, float life, float width, - float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b ) -{ - BEAM *pbeam = R_BeamLightning( start, end, modelIndex, life, width, amplitude, brightness, speed ); - - if( !pbeam ) return NULL; - pbeam->type = type; - if( life == 0 ) SetBits( pbeam->flags, FBEAM_FOREVER ); - R_BeamSetAttributes( pbeam, r, g, b, framerate, startFrame ); - - return pbeam; -} - - -/* -============== -R_BeamEntPoint - -Create beam between entity and point -============== -*/ -BEAM *R_BeamEntPoint( int startEnt, vec3_t end, int modelIndex, float life, float width, float amplitude, - float brightness, float speed, int startFrame, float framerate, float r, float g, float b ) -{ - BEAM *pbeam; - cl_entity_t *start; - - start = R_BeamGetEntity( startEnt ); - - if( !start ) return NULL; - - if( life == 0 && !start->model ) - return NULL; - - pbeam = R_BeamAlloc(); - if ( !pbeam ) return NULL; - - pbeam->die = cl.time; - if( modelIndex < 0 ) - return NULL; - - R_BeamSetup( pbeam, vec3_origin, end, modelIndex, life, width, amplitude, brightness, speed ); - - pbeam->type = TE_BEAMPOINTS; - SetBits( pbeam->flags, FBEAM_STARTENTITY ); - if( life == 0 ) SetBits( pbeam->flags, FBEAM_FOREVER ); - pbeam->startEntity = startEnt; - pbeam->endEntity = 0; - - R_BeamSetAttributes( pbeam, r, g, b, framerate, startFrame ); - - return pbeam; -} - -/* -============== -R_BeamRing - -Create beam between two ents -============== -*/ -BEAM *R_BeamRing( int startEnt, int endEnt, int modelIndex, float life, float width, float amplitude, float brightness, - float speed, int startFrame, float framerate, float r, float g, float b ) -{ - BEAM *pbeam; - cl_entity_t *start, *end; - - start = R_BeamGetEntity( startEnt ); - end = R_BeamGetEntity( endEnt ); - - if( !start || !end ) - return NULL; - - if( life != 0 && ( !start->model || !end->model )) - return NULL; - - pbeam = R_BeamLightning( vec3_origin, vec3_origin, modelIndex, life, width, amplitude, brightness, speed ); - if( !pbeam ) return NULL; - - pbeam->type = TE_BEAMRING; - SetBits( pbeam->flags, FBEAM_STARTENTITY | FBEAM_ENDENTITY ); - if( life == 0 ) SetBits( pbeam->flags, FBEAM_FOREVER ); - pbeam->startEntity = startEnt; - pbeam->endEntity = endEnt; - - R_BeamSetAttributes( pbeam, r, g, b, framerate, startFrame ); - - return pbeam; -} - -/* -============== -R_BeamFollow - -Create beam following with entity -============== -*/ -BEAM *R_BeamFollow( int startEnt, int modelIndex, float life, float width, float r, float g, float b, float brightness ) -{ - BEAM *pbeam = R_BeamAlloc(); - - if( !pbeam ) return NULL; - pbeam->die = cl.time; - - if( modelIndex < 0 ) - return NULL; - - R_BeamSetup( pbeam, vec3_origin, vec3_origin, modelIndex, life, width, life, brightness, 1.0f ); - - pbeam->type = TE_BEAMFOLLOW; - SetBits( pbeam->flags, FBEAM_STARTENTITY ); - pbeam->startEntity = startEnt; - - R_BeamSetAttributes( pbeam, r, g, b, 1.0f, 0 ); - - return pbeam; -} - -/* -============== -R_BeamSprite - -Create a beam with sprite at the end -Valve legacy -============== -*/ -void R_BeamSprite( vec3_t start, vec3_t end, int beamIndex, int spriteIndex ) -{ - R_BeamPoints( start, end, beamIndex, 0.01f, 0.4f, 0, COM_RandomFloat( 0.5f, 0.655f ), 5.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f ); - R_TempSprite( end, vec3_origin, 0.1f, spriteIndex, kRenderTransAdd, kRenderFxNone, 0.35f, 0.01f, 0.0f ); -} - -/* -============== -CL_ParseViewBeam - -handle beam messages -============== -*/ -void CL_ParseViewBeam( sizebuf_t *msg, int beamType ) -{ - vec3_t start, end; - int modelIndex, startFrame; - float frameRate, life, width; - int startEnt, endEnt; - float noise, speed; - float r, g, b, a; - - switch( beamType ) - { - case TE_BEAMPOINTS: - start[0] = MSG_ReadCoord( msg ); - start[1] = MSG_ReadCoord( msg ); - start[2] = MSG_ReadCoord( msg ); - end[0] = MSG_ReadCoord( msg ); - end[1] = MSG_ReadCoord( msg ); - end[2] = MSG_ReadCoord( msg ); - modelIndex = MSG_ReadShort( msg ); - startFrame = MSG_ReadByte( msg ); - frameRate = (float)MSG_ReadByte( msg ); - life = (float)(MSG_ReadByte( msg ) * 0.1f); - width = (float)(MSG_ReadByte( msg ) * 0.1f); - noise = (float)(MSG_ReadByte( msg ) * 0.01f); - r = (float)MSG_ReadByte( msg ) / 255.0f; - g = (float)MSG_ReadByte( msg ) / 255.0f; - b = (float)MSG_ReadByte( msg ) / 255.0f; - a = (float)MSG_ReadByte( msg ) / 255.0f; - speed = (float)(MSG_ReadByte( msg ) * 0.1f); - R_BeamPoints( start, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b ); - break; - case TE_BEAMENTPOINT: - startEnt = MSG_ReadShort( msg ); - end[0] = MSG_ReadCoord( msg ); - end[1] = MSG_ReadCoord( msg ); - end[2] = MSG_ReadCoord( msg ); - modelIndex = MSG_ReadShort( msg ); - startFrame = MSG_ReadByte( msg ); - frameRate = (float)MSG_ReadByte( msg ); - life = (float)(MSG_ReadByte( msg ) * 0.1f); - width = (float)(MSG_ReadByte( msg ) * 0.1f); - noise = (float)(MSG_ReadByte( msg ) * 0.01f); - r = (float)MSG_ReadByte( msg ) / 255.0f; - g = (float)MSG_ReadByte( msg ) / 255.0f; - b = (float)MSG_ReadByte( msg ) / 255.0f; - a = (float)MSG_ReadByte( msg ) / 255.0f; - speed = (float)(MSG_ReadByte( msg ) * 0.1f); - R_BeamEntPoint( startEnt, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b ); - break; - case TE_LIGHTNING: - start[0] = MSG_ReadCoord( msg ); - start[1] = MSG_ReadCoord( msg ); - start[2] = MSG_ReadCoord( msg ); - end[0] = MSG_ReadCoord( msg ); - end[1] = MSG_ReadCoord( msg ); - end[2] = MSG_ReadCoord( msg ); - life = (float)(MSG_ReadByte( msg ) * 0.1f); - width = (float)(MSG_ReadByte( msg ) * 0.1f); - noise = (float)(MSG_ReadByte( msg ) * 0.01f); - modelIndex = MSG_ReadShort( msg ); - R_BeamLightning( start, end, modelIndex, life, width, noise, 0.6F, 3.5f ); - break; - case TE_BEAMENTS: - startEnt = MSG_ReadShort( msg ); - endEnt = MSG_ReadShort( msg ); - modelIndex = MSG_ReadShort( msg ); - startFrame = MSG_ReadByte( msg ); - frameRate = (float)(MSG_ReadByte( msg ) * 0.1f); - life = (float)(MSG_ReadByte( msg ) * 0.1f); - width = (float)(MSG_ReadByte( msg ) * 0.1f); - noise = (float)(MSG_ReadByte( msg ) * 0.01f); - r = (float)MSG_ReadByte( msg ) / 255.0f; - g = (float)MSG_ReadByte( msg ) / 255.0f; - b = (float)MSG_ReadByte( msg ) / 255.0f; - a = (float)MSG_ReadByte( msg ) / 255.0f; - speed = (float)(MSG_ReadByte( msg ) * 0.1f); - R_BeamEnts( startEnt, endEnt, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b ); - break; - case TE_BEAM: - break; - case TE_BEAMSPRITE: - start[0] = MSG_ReadCoord( msg ); - start[1] = MSG_ReadCoord( msg ); - start[2] = MSG_ReadCoord( msg ); - end[0] = MSG_ReadCoord( msg ); - end[1] = MSG_ReadCoord( msg ); - end[2] = MSG_ReadCoord( msg ); - modelIndex = MSG_ReadShort( msg ); // beam model - startFrame = MSG_ReadShort( msg ); // sprite model - R_BeamSprite( start, end, modelIndex, startFrame ); - break; - case TE_BEAMTORUS: - case TE_BEAMDISK: - case TE_BEAMCYLINDER: - start[0] = MSG_ReadCoord( msg ); - start[1] = MSG_ReadCoord( msg ); - start[2] = MSG_ReadCoord( msg ); - end[0] = MSG_ReadCoord( msg ); - end[1] = MSG_ReadCoord( msg ); - end[2] = MSG_ReadCoord( msg ); - modelIndex = MSG_ReadShort( msg ); - startFrame = MSG_ReadByte( msg ); - frameRate = (float)(MSG_ReadByte( msg )); - life = (float)(MSG_ReadByte( msg ) * 0.1f); - width = (float)(MSG_ReadByte( msg )); - noise = (float)(MSG_ReadByte( msg ) * 0.1f); - r = (float)MSG_ReadByte( msg ) / 255.0f; - g = (float)MSG_ReadByte( msg ) / 255.0f; - b = (float)MSG_ReadByte( msg ) / 255.0f; - a = (float)MSG_ReadByte( msg ) / 255.0f; - speed = (float)(MSG_ReadByte( msg ) / 0.1f); - R_BeamCirclePoints( beamType, start, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b ); - break; - case TE_BEAMFOLLOW: - startEnt = MSG_ReadShort( msg ); - modelIndex = MSG_ReadShort( msg ); - life = (float)(MSG_ReadByte( msg ) * 0.1f); - width = (float)MSG_ReadByte( msg ); - r = (float)MSG_ReadByte( msg ) / 255.0f; - g = (float)MSG_ReadByte( msg ) / 255.0f; - b = (float)MSG_ReadByte( msg ) / 255.0f; - a = (float)MSG_ReadByte( msg ) / 255.0f; - R_BeamFollow( startEnt, modelIndex, life, width, r, g, b, a ); - break; - case TE_BEAMRING: - startEnt = MSG_ReadShort( msg ); - endEnt = MSG_ReadShort( msg ); - modelIndex = MSG_ReadShort( msg ); - startFrame = MSG_ReadByte( msg ); - frameRate = (float)MSG_ReadByte( msg ); - life = (float)(MSG_ReadByte( msg ) * 0.1f); - width = (float)(MSG_ReadByte( msg ) * 0.1f); - noise = (float)(MSG_ReadByte( msg ) * 0.01f); - r = (float)MSG_ReadByte( msg ) / 255.0f; - g = (float)MSG_ReadByte( msg ) / 255.0f; - b = (float)MSG_ReadByte( msg ) / 255.0f; - a = (float)MSG_ReadByte( msg ) / 255.0f; - speed = (float)(MSG_ReadByte( msg ) * 0.1f); - R_BeamRing( startEnt, endEnt, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b ); - break; - case TE_BEAMHOSE: - break; - case TE_KILLBEAM: - startEnt = MSG_ReadShort( msg ); - R_BeamKill( startEnt ); - break; - } -} - -/* -=============== -CL_ReadLineFile_f - -Optimized version of pointfile - use beams instead of particles -=============== -*/ -void CL_ReadLineFile_f( void ) -{ - char *afile, *pfile; - vec3_t p1, p2; - int count, modelIndex; - char filename[MAX_QPATH]; - model_t *model; - string token; - - Q_snprintf( filename, sizeof( filename ), "maps/%s.lin", clgame.mapname ); - afile = FS_LoadFile( filename, NULL, false ); - - if( !afile ) - { - Con_Printf( S_ERROR "couldn't open %s\n", filename ); - return; - } - - Con_Printf( "Reading %s...\n", filename ); - - count = 0; - pfile = afile; - model = CL_LoadModel( DEFAULT_LASERBEAM_PATH, &modelIndex ); - - while( 1 ) - { - pfile = COM_ParseFile( pfile, token ); - if( !pfile ) break; - p1[0] = Q_atof( token ); - - pfile = COM_ParseFile( pfile, token ); - if( !pfile ) break; - p1[1] = Q_atof( token ); - - pfile = COM_ParseFile( pfile, token ); - if( !pfile ) break; - p1[2] = Q_atof( token ); - - pfile = COM_ParseFile( pfile, token ); - if( !pfile ) break; - - if( token[0] != '-' ) - { - Con_Printf( S_ERROR "%s is corrupted\n", filename ); - break; - } - - pfile = COM_ParseFile( pfile, token ); - if( !pfile ) break; - p2[0] = Q_atof( token ); - - pfile = COM_ParseFile( pfile, token ); - if( !pfile ) break; - p2[1] = Q_atof( token ); - - pfile = COM_ParseFile( pfile, token ); - if( !pfile ) break; - p2[2] = Q_atof( token ); - - count++; - - if( !R_BeamPoints( p1, p2, modelIndex, 0, 2, 0, 255, 0, 0, 0, 255.0f, 0.0f, 0.0f )) - { - if( !model || model->type != mod_sprite ) - Con_Printf( S_ERROR "failed to load \"%s\"!\n", DEFAULT_LASERBEAM_PATH ); - else Con_Printf( S_ERROR "not enough free beams!\n" ); - break; - } - } - - Mem_Free( afile ); - - if( count ) Con_Printf( "%i lines read\n", count ); - else Con_Printf( "map %s has no leaks!\n", clgame.mapname ); -} diff --git a/ref_gl/gl_context.c b/ref_gl/gl_context.c index c38dc185..c84b7d03 100644 --- a/ref_gl/gl_context.c +++ b/ref_gl/gl_context.c @@ -12,8 +12,7 @@ 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. */ -#include "common.h" -#include "client.h" + #include "gl_local.h" #include "gl_export.h" diff --git a/ref_gl/gl_cull.c b/ref_gl/gl_cull.c index d786651e..be6bec1b 100644 --- a/ref_gl/gl_cull.c +++ b/ref_gl/gl_cull.c @@ -13,8 +13,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" -#include "client.h" #include "gl_local.h" #include "entity_types.h" @@ -148,4 +146,4 @@ int R_CullSurface( msurface_t *surf, gl_frustum_t *frustum, uint clipflags ) return CULL_FRUSTUM; return CULL_VISIBLE; -} \ No newline at end of file +} diff --git a/ref_gl/gl_dbghulls.c b/ref_gl/gl_dbghulls.c index 662e8cc6..729b333b 100644 --- a/ref_gl/gl_dbghulls.c +++ b/ref_gl/gl_dbghulls.c @@ -14,11 +14,7 @@ GNU General Public License for more details. */ -#include "mod_local.h" -#include "mathlib.h" -#include "world.h" #include "gl_local.h" -#include "client.h" #define list_entry( ptr, type, member ) \ ((type *)((char *)(ptr) - (size_t)(&((type *)0)->member))) @@ -31,7 +27,7 @@ GNU General Public License for more details. void R_DrawWorldHull( void ) { - hull_model_t *hull = &world.hull_models[0]; + hull_model_t *hull = &WORLDMODEL->hull_models[0]; winding_t *poly; int i; @@ -71,10 +67,10 @@ void R_DrawModelHull( void ) return; i = atoi( RI.currentmodel->name + 1 ); - if( i < 1 || i >= world.num_hull_models ) + if( i < 1 || i >= WORLDMODEL->num_hull_models ) return; - hull = &world.hull_models[i]; + hull = &WORLDMODEL->hull_models[i]; pglPolygonOffset( 1.0f, 2.0 ); pglEnable( GL_POLYGON_OFFSET_FILL ); diff --git a/ref_gl/gl_decals.c b/ref_gl/gl_decals.c index 0c7ea2c6..9638e7cd 100644 --- a/ref_gl/gl_decals.c +++ b/ref_gl/gl_decals.c @@ -13,8 +13,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" -#include "client.h" #include "gl_local.h" #include "cl_tent.h" @@ -774,7 +772,7 @@ void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos } else if( modelIndex > 0 ) model = CL_ModelHandle( modelIndex ); - else model = cl.worldmodel; + else model = WORLDMODEL; if( !model ) return; @@ -1163,7 +1161,7 @@ int R_CreateDecalList( decallist_t *pList ) int total = 0; int i, depth; - if( cl.worldmodel ) + if( WORLDMODEL ) { for( i = 0; i < MAX_RENDER_DECALS; i++ ) { diff --git a/ref_gl/gl_draw.c b/ref_gl/gl_draw.c index 63178b26..cd455380 100644 --- a/ref_gl/gl_draw.c +++ b/ref_gl/gl_draw.c @@ -13,8 +13,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" -#include "client.h" #include "gl_local.h" /* @@ -280,4 +278,4 @@ void R_Set2DMode( qboolean enable ) GL_Cull( GL_FRONT ); } -} \ No newline at end of file +} diff --git a/ref_gl/gl_frustum.c b/ref_gl/gl_frustum.c index aa1c0a5d..64c56118 100644 --- a/ref_gl/gl_frustum.c +++ b/ref_gl/gl_frustum.c @@ -13,7 +13,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" #include "gl_local.h" #include "mathlib.h" diff --git a/ref_gl/gl_image.c b/ref_gl/gl_image.c index 63132535..a2b97553 100644 --- a/ref_gl/gl_image.c +++ b/ref_gl/gl_image.c @@ -13,8 +13,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" -#include "client.h" #include "gl_local.h" #define TEXTURES_HASH_SIZE (MAX_TEXTURES >> 2) diff --git a/ref_gl/gl_local.h b/ref_gl/gl_local.h index 2a718bdd..3755989b 100644 --- a/ref_gl/gl_local.h +++ b/ref_gl/gl_local.h @@ -15,7 +15,11 @@ GNU General Public License for more details. #ifndef GL_LOCAL_H #define GL_LOCAL_H - +#include "port.h" +#include "xash3d_types.h" +#include "cvardef.h" +#include "const.h" +#include "com_model.h" #include "gl_export.h" #include "cl_entity.h" #include "render_api.h" @@ -23,6 +27,62 @@ GNU General Public License for more details. #include "dlight.h" #include "gl_frustum.h" #include "ref_api.h" +#include "mathlib.h" +#include "ref_params.h" +#include "enginefeatures.h" +#include "com_strings.h" +#include "pm_movevars.h" +typedef cvar_t convar_t; +#include +#define Con_Reportf printf +#define Con_Printf printf +#define Con_DPrintf printf + +void CL_DrawEFX(double, double); +void *CL_ModelHandle(int); +void *GL_GetProcAddress(char *); +void GL_CheckForErrors(); +void CL_ExtraUpdate(); +void Cbuf_AddText(char*); +void Cbuf_Execute(); +int COM_HashKey(char*,int); +extern convar_t cvstub; +#define Cvar_Get(...) &cvstub +#define Cvar_FindVar(...) &cvstub +#define Cvar_SetValue(...) +#define Cmd_AddCommand(...) +#define Cmd_RemoveCommand(...) +#define FS_FreeImage(...) +#define Host_Error(...) +#define ASSERT(x) +#define Q_strcpy(...) +#define Q_strncpy(...) +#define Q_strncat(...) +#define Q_strnat(...) +#define Q_snprintf(...) +#define Q_strcmp(...) 1 +#define Q_stricmp(...) 1 +#define Q_strncmp(...) 1 +#define Q_strnicmp(...) 1 +#define Q_strlen(...) 1 +#define Assert(x) +#define va(...) ((const char*)NULL) + +void *FS_LoadImage(char *, void *, int); +void *FS_CopyImage(void *); +void *Mem_Calloc(void*, int); +void *Mem_Malloc(void*, int); + +void *Mem_Realloc(void*,void*, int); + + +#define CVAR_DEFINE( cv, cvname, cvstr, cvflags, cvdesc ) convar_t cv = { cvname, cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, cvdesc } +#define CVAR_DEFINE_AUTO( cv, cvstr, cvflags, cvdesc ) convar_t cv = { #cv, cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, cvdesc } +#define CVAR_TO_BOOL( x ) ((x) && ((x)->value != 0.0f) ? true : false ) + +#define WORLDMODEL ((model_t*)NULL) +#define MOVEVARS ((movevars_t*)NULL) + extern byte *r_temppool; @@ -593,10 +653,8 @@ typedef struct typedef struct { - int width, height; - qboolean fullScreen; - qboolean wideScreen; + int width, height; int activeTMU; GLint currentTextures[MAX_TEXTURE_UNITS]; GLuint currentTextureTargets[MAX_TEXTURE_UNITS]; @@ -610,18 +668,7 @@ typedef struct qboolean in2DMode; } glstate_t; -typedef enum -{ - SAFE_NO = 0, - SAFE_NOMSAA, // skip msaa - SAFE_NOACC, // don't set acceleration flag - SAFE_NOSTENCIL, // don't set stencil bits - SAFE_NOALPHA, // don't set alpha bits - SAFE_NODEPTH, // don't set depth bits - SAFE_NOCOLOR, // don't set color bits - SAFE_DONTCARE // ignore everything, let SDL/EGL decide -} safe_context_t; - +/* typedef struct { void* context; // handle to GL rendering context @@ -634,10 +681,12 @@ typedef struct qboolean initialized; // OpenGL subsystem started qboolean extended; // extended context allows to GL_Debug } glwstate_t; +*/ extern glconfig_t glConfig; extern glstate_t glState; -extern glwstate_t glw_state; +// move to engine +//extern glwstate_t glw_state; // // renderer cvars diff --git a/ref_gl/gl_opengl.c b/ref_gl/gl_opengl.c new file mode 100644 index 00000000..89539f54 --- /dev/null +++ b/ref_gl/gl_opengl.c @@ -0,0 +1,518 @@ + +#include "gl_local.h" + +convar_t *gl_extensions; +convar_t *gl_texture_anisotropy; +convar_t *gl_texture_lodbias; +convar_t *gl_texture_nearest; +convar_t *gl_lightmap_nearest; +convar_t *gl_keeptjunctions; +convar_t *gl_emboss_scale; +convar_t *gl_detailscale; +convar_t *gl_check_errors; +convar_t *gl_polyoffset; +convar_t *gl_wireframe; +convar_t *gl_finish; +convar_t *gl_nosort; +convar_t *gl_vsync; +convar_t *gl_clear; +convar_t *gl_test; +convar_t *gl_msaa; +convar_t *gl_stencilbits; +convar_t *r_speeds; +convar_t *r_fullbright; +convar_t *r_norefresh; +convar_t *r_showtree; +convar_t *r_lighting_extended; +convar_t *r_lighting_modulate; +convar_t *r_lighting_ambient; +convar_t *r_detailtextures; +convar_t *r_drawentities; +convar_t *r_adjust_fov; +convar_t *r_decals; +convar_t *r_novis; +convar_t *r_nocull; +convar_t *r_lockpvs; +convar_t *r_lockfrustum; +convar_t *r_traceglow; +convar_t *r_dynamic; +convar_t *r_lightmap; +convar_t *gl_round_down; +convar_t *r_vbo; +convar_t *r_vbo_dlightmode; + +byte *r_temppool; + +gl_globals_t tr; +glconfig_t glConfig; +glstate_t glState; +glwstate_t glw_state; + +/* +================= +GL_SetExtension +================= +*/ +void GL_SetExtension( int r_ext, int enable ) +{ + if( r_ext >= 0 && r_ext < GL_EXTCOUNT ) + glConfig.extension[r_ext] = enable ? GL_TRUE : GL_FALSE; + else Con_Printf( S_ERROR "GL_SetExtension: invalid extension %d\n", r_ext ); +} + +/* +================= +GL_Support +================= +*/ +qboolean GL_Support( int r_ext ) +{ + if( r_ext >= 0 && r_ext < GL_EXTCOUNT ) + return glConfig.extension[r_ext] ? true : false; + Con_Printf( S_ERROR "GL_Support: invalid extension %d\n", r_ext ); + + return false; +} + +/* +================= +GL_MaxTextureUnits +================= +*/ +int GL_MaxTextureUnits( void ) +{ + if( GL_Support( GL_SHADER_GLSL100_EXT )) + return Q_min( Q_max( glConfig.max_texture_coords, glConfig.max_teximage_units ), MAX_TEXTURE_UNITS ); + return glConfig.max_texture_units; +} + +/* +================= +GL_CheckExtension +================= +*/ +void GL_CheckExtension( const char *name, const dllfunc_t *funcs, const char *cvarname, int r_ext ) +{ + const dllfunc_t *func; + convar_t *parm = NULL; + const char *extensions_string; + + Con_Reportf( "GL_CheckExtension: %s ", name ); + GL_SetExtension( r_ext, true ); + + if( cvarname ) + { + // system config disable extensions + parm = Cvar_Get( cvarname, "1", FCVAR_GLCONFIG, va( CVAR_GLCONFIG_DESCRIPTION, name )); + } + + if(( parm && !CVAR_TO_BOOL( parm )) || ( !CVAR_TO_BOOL( gl_extensions ) && r_ext != GL_OPENGL_110 )) + { + Con_Reportf( "- disabled\n" ); + GL_SetExtension( r_ext, false ); + return; // nothing to process at + } + + extensions_string = glConfig.extensions_string; + + if(( name[2] == '_' || name[3] == '_' ) && !Q_strstr( extensions_string, name )) + { + GL_SetExtension( r_ext, false ); // update render info + Con_Reportf( "- ^1failed\n" ); + return; + } + + // clear exports + for( func = funcs; func && func->name; func++ ) + *func->func = NULL; + + for( func = funcs; func && func->name != NULL; func++ ) + { + // functions are cleared before all the extensions are evaluated + if((*func->func = (void *)GL_GetProcAddress( func->name )) == NULL ) + GL_SetExtension( r_ext, false ); // one or more functions are invalid, extension will be disabled + } + + if( GL_Support( r_ext )) + Con_Reportf( "- ^2enabled\n" ); + else Con_Reportf( "- ^1failed\n" ); +} + +/* +=============== +GL_SetDefaultTexState +=============== +*/ +static void GL_SetDefaultTexState( void ) +{ + + int i; + + memset( glState.currentTextures, -1, MAX_TEXTURE_UNITS * sizeof( *glState.currentTextures )); + memset( glState.texCoordArrayMode, 0, MAX_TEXTURE_UNITS * sizeof( *glState.texCoordArrayMode )); + memset( glState.genSTEnabled, 0, MAX_TEXTURE_UNITS * sizeof( *glState.genSTEnabled )); + + for( i = 0; i < MAX_TEXTURE_UNITS; i++ ) + { + glState.currentTextureTargets[i] = GL_NONE; + glState.texIdentityMatrix[i] = true; + } +} + +/* +=============== +GL_SetDefaultState +=============== +*/ +static void GL_SetDefaultState( void ) +{ + memset( &glState, 0, sizeof( glState )); + GL_SetDefaultTexState (); + + // init draw stack + tr.draw_list = &tr.draw_stack[0]; + tr.draw_stack_pos = 0; +} + +/* +=============== +GL_SetDefaults +=============== +*/ +static void GL_SetDefaults( void ) +{ + pglFinish(); + + pglClearColor( 0.5f, 0.5f, 0.5f, 1.0f ); + + pglDisable( GL_DEPTH_TEST ); + pglDisable( GL_CULL_FACE ); + pglDisable( GL_SCISSOR_TEST ); + pglDepthFunc( GL_LEQUAL ); + pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); + + if( vidState.stencilEnabled ) + { + pglDisable( GL_STENCIL_TEST ); + pglStencilMask( ( GLuint ) ~0 ); + pglStencilFunc( GL_EQUAL, 0, ~0 ); + pglStencilOp( GL_KEEP, GL_INCR, GL_INCR ); + } + + pglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + pglPolygonOffset( -1.0f, -2.0f ); + + GL_CleanupAllTextureUnits(); + + pglDisable( GL_BLEND ); + pglDisable( GL_ALPHA_TEST ); + pglDisable( GL_POLYGON_OFFSET_FILL ); + pglAlphaFunc( GL_GREATER, DEFAULT_ALPHATEST ); + pglEnable( GL_TEXTURE_2D ); + pglShadeModel( GL_SMOOTH ); + pglFrontFace( GL_CCW ); + + pglPointSize( 1.2f ); + pglLineWidth( 1.2f ); + + GL_Cull( GL_NONE ); +} + + +/* +================= +R_RenderInfo_f +================= +*/ +void R_RenderInfo_f( void ) +{ + Con_Printf( "\n" ); + Con_Printf( "GL_VENDOR: %s\n", glConfig.vendor_string ); + Con_Printf( "GL_RENDERER: %s\n", glConfig.renderer_string ); + Con_Printf( "GL_VERSION: %s\n", glConfig.version_string ); + + // don't spam about extensions + if( host_developer.value >= DEV_EXTENDED ) + { + Con_Printf( "GL_EXTENSIONS: %s\n", glConfig.extensions_string ); + } + + Con_Printf( "GL_MAX_TEXTURE_SIZE: %i\n", glConfig.max_2d_texture_size ); + + if( GL_Support( GL_ARB_MULTITEXTURE )) + Con_Printf( "GL_MAX_TEXTURE_UNITS_ARB: %i\n", glConfig.max_texture_units ); + if( GL_Support( GL_TEXTURE_CUBEMAP_EXT )) + Con_Printf( "GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB: %i\n", glConfig.max_cubemap_size ); + if( GL_Support( GL_ANISOTROPY_EXT )) + Con_Printf( "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: %.1f\n", glConfig.max_texture_anisotropy ); + if( GL_Support( GL_TEXTURE_2D_RECT_EXT )) + Con_Printf( "GL_MAX_RECTANGLE_TEXTURE_SIZE: %i\n", glConfig.max_2d_rectangle_size ); + if( GL_Support( GL_TEXTURE_ARRAY_EXT )) + Con_Printf( "GL_MAX_ARRAY_TEXTURE_LAYERS_EXT: %i\n", glConfig.max_2d_texture_layers ); + if( GL_Support( GL_SHADER_GLSL100_EXT )) + { + Con_Printf( "GL_MAX_TEXTURE_COORDS_ARB: %i\n", glConfig.max_texture_coords ); + Con_Printf( "GL_MAX_TEXTURE_IMAGE_UNITS_ARB: %i\n", glConfig.max_teximage_units ); + Con_Printf( "GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB: %i\n", glConfig.max_vertex_uniforms ); + Con_Printf( "GL_MAX_VERTEX_ATTRIBS_ARB: %i\n", glConfig.max_vertex_attribs ); + } + + Con_Printf( "\n" ); + Con_Printf( "MODE: %ix%i\n", vidState.width, vidState.height ); + Con_Printf( "\n" ); + Con_Printf( "VERTICAL SYNC: %s\n", gl_vsync->value ? "enabled" : "disabled" ); + Con_Printf( "Color %d bits, Alpha %d bits, Depth %d bits, Stencil %d bits\n", glConfig.color_bits, + glConfig.alpha_bits, glConfig.depth_bits, glConfig.stencil_bits ); +} + +//======================================================================= + +/* +================= +GL_InitCommands +================= +*/ +void GL_InitCommands( void ) +{ + // system screen width and height (don't suppose for change from console at all) + Cvar_Get( "width", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen width" ); + Cvar_Get( "height", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen height" ); + r_speeds = Cvar_Get( "r_speeds", "0", FCVAR_ARCHIVE, "shows renderer speeds" ); + r_fullbright = Cvar_Get( "r_fullbright", "0", FCVAR_CHEAT, "disable lightmaps, get fullbright for entities" ); + r_norefresh = Cvar_Get( "r_norefresh", "0", 0, "disable 3D rendering (use with caution)" ); + r_showtree = Cvar_Get( "r_showtree", "0", FCVAR_ARCHIVE, "build the graph of visible BSP tree" ); + r_lighting_extended = Cvar_Get( "r_lighting_extended", "1", FCVAR_ARCHIVE, "allow to get lighting from world and bmodels" ); + r_lighting_modulate = Cvar_Get( "r_lighting_modulate", "0.6", FCVAR_ARCHIVE, "lightstyles modulate scale" ); + r_lighting_ambient = Cvar_Get( "r_lighting_ambient", "0.3", FCVAR_ARCHIVE, "map ambient lighting scale" ); + r_novis = Cvar_Get( "r_novis", "0", 0, "ignore vis information (perfomance test)" ); + r_nocull = Cvar_Get( "r_nocull", "0", 0, "ignore frustrum culling (perfomance test)" ); + r_detailtextures = Cvar_Get( "r_detailtextures", "1", FCVAR_ARCHIVE, "enable detail textures support, use '2' for autogenerate detail.txt" ); + r_lockpvs = Cvar_Get( "r_lockpvs", "0", FCVAR_CHEAT, "lockpvs area at current point (pvs test)" ); + r_lockfrustum = Cvar_Get( "r_lockfrustum", "0", FCVAR_CHEAT, "lock frustrum area at current point (cull test)" ); + r_dynamic = Cvar_Get( "r_dynamic", "1", FCVAR_ARCHIVE, "allow dynamic lighting (dlights, lightstyles)" ); + r_traceglow = Cvar_Get( "r_traceglow", "1", FCVAR_ARCHIVE, "cull flares behind models" ); + r_lightmap = Cvar_Get( "r_lightmap", "0", FCVAR_CHEAT, "lightmap debugging tool" ); + r_drawentities = Cvar_Get( "r_drawentities", "1", FCVAR_CHEAT, "render entities" ); + r_decals = engine.Cvar_Find( "r_decals" ); + window_xpos = Cvar_Get( "_window_xpos", "130", FCVAR_RENDERINFO, "window position by horizontal" ); + window_ypos = Cvar_Get( "_window_ypos", "48", FCVAR_RENDERINFO, "window position by vertical" ); + + gl_extensions = Cvar_Get( "gl_allow_extensions", "1", FCVAR_GLCONFIG, "allow gl_extensions" ); + gl_texture_nearest = Cvar_Get( "gl_texture_nearest", "0", FCVAR_ARCHIVE, "disable texture filter" ); + gl_lightmap_nearest = Cvar_Get( "gl_lightmap_nearest", "0", FCVAR_ARCHIVE, "disable lightmap filter" ); + gl_check_errors = Cvar_Get( "gl_check_errors", "1", FCVAR_ARCHIVE, "ignore video engine errors" ); + gl_vsync = engine.Cvar_Find( "gl_vsync" ); + gl_detailscale = Cvar_Get( "gl_detailscale", "4.0", FCVAR_ARCHIVE, "default scale applies while auto-generate list of detail textures" ); + gl_texture_anisotropy = Cvar_Get( "gl_anisotropy", "8", FCVAR_ARCHIVE, "textures anisotropic filter" ); + gl_texture_lodbias = Cvar_Get( "gl_texture_lodbias", "0.0", FCVAR_ARCHIVE, "LOD bias for mipmapped textures (perfomance|quality)" ); + gl_keeptjunctions = Cvar_Get( "gl_keeptjunctions", "1", FCVAR_ARCHIVE, "removing tjuncs causes blinking pixels" ); + gl_emboss_scale = Cvar_Get( "gl_emboss_scale", "0", FCVAR_ARCHIVE|FCVAR_LATCH, "fake bumpmapping scale" ); + gl_showtextures = engine.Cvar_Find( "r_showtextures" ); + gl_finish = Cvar_Get( "gl_finish", "0", FCVAR_ARCHIVE, "use glFinish instead of glFlush" ); + gl_nosort = Cvar_Get( "gl_nosort", "0", FCVAR_ARCHIVE, "disable sorting of translucent surfaces" ); + gl_clear = Cvar_Get( "gl_clear", "0", FCVAR_ARCHIVE, "clearing screen after each frame" ); + gl_test = Cvar_Get( "gl_test", "0", 0, "engine developer cvar for quick testing new features" ); + gl_wireframe = Cvar_Get( "gl_wireframe", "0", FCVAR_ARCHIVE|FCVAR_SPONLY, "show wireframe overlay" ); + gl_wgl_msaa_samples = Cvar_Get( "gl_wgl_msaa_samples", "0", FCVAR_GLCONFIG, "samples number for multisample anti-aliasing" ); + gl_msaa = Cvar_Get( "gl_msaa", "1", FCVAR_ARCHIVE, "enable or disable multisample anti-aliasing" ); + gl_stencilbits = Cvar_Get( "gl_stencilbits", "8", FCVAR_GLCONFIG, "pixelformat stencil bits (0 - auto)" ); + gl_round_down = Cvar_Get( "gl_round_down", "2", FCVAR_RENDERINFO, "round texture sizes to nearest POT value" ); + // these cvar not used by engine but some mods requires this + gl_polyoffset = Cvar_Get( "gl_polyoffset", "2.0", FCVAR_ARCHIVE, "polygon offset for decals" ); + + // make sure gl_vsync is checked after vid_restart + SetBits( gl_vsync->flags, FCVAR_CHANGED ); + + vid_gamma = Cvar_Get( "gamma", "2.5", FCVAR_ARCHIVE, "gamma amount" ); + vid_brightness = Cvar_Get( "brightness", "0.0", FCVAR_ARCHIVE, "brightness factor" ); + vid_fullscreen = engine.Cvar_Find( "fullscreen" ); + vid_displayfrequency = engine.Cvar_Find ( "vid_displayfrequency" ); + vid_highdpi = Cvar_Get( "vid_highdpi", "1", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable High-DPI mode" ); + + Cmd_AddCommand( "r_info", R_RenderInfo_f, "display renderer info" ); + Cmd_AddCommand( "timerefresh", SCR_TimeRefresh_f, "turn quickly and print rendering statistcs" ); + + // a1ba: planned to be named vid_mode for compability + // but supported mode list is filled by backends, so numbers are not portable any more + Cmd_AddCommand( "vid_setmode", VID_Mode_f, "display video mode" ); + + // give initial OpenGL configuration + host.apply_opengl_config = true; + Cbuf_AddText( "exec opengl.cfg\n" ); + Cbuf_Execute(); + host.apply_opengl_config = false; + + // apply actual video mode to window + Cbuf_AddText( "exec video.cfg\n" ); + Cbuf_Execute(); +} + +/* +=============== +R_CheckVBO + +register VBO cvars and get default value +=============== +*/ +static void R_CheckVBO( void ) +{ + const char *def = "1"; + const char *dlightmode = "1"; + int flags = FCVAR_ARCHIVE; + qboolean disable = false; + + // some bad GLES1 implementations breaks dlights completely + if( glConfig.max_texture_units < 3 ) + disable = true; + +#ifdef XASH_MOBILE_PLATFORM + // VideoCore4 drivers have a problem with mixing VBO and client arrays + // Disable it, as there is no suitable workaround here + if( Q_stristr( glConfig.renderer_string, "VideoCore IV" ) || Q_stristr( glConfig.renderer_string, "vc4" ) ) + disable = true; + + // dlightmode 1 is not too much tested on android + // so better to left it off + dlightmode = "0"; +#endif + + if( disable ) + { + // do not keep in config unless dev > 3 and enabled + flags = 0; + def = "0"; + } + + r_vbo = Cvar_Get( "r_vbo", def, flags, "draw world using VBO" ); + r_vbo_dlightmode = Cvar_Get( "r_vbo_dlightmode", dlightmode, FCVAR_ARCHIVE, "vbo dlight rendering mode(0-1)" ); + + // check if enabled manually + if( CVAR_TO_BOOL(r_vbo) ) + r_vbo->flags |= FCVAR_ARCHIVE; +} + + +/* +=============== +R_Init +=============== +*/ +qboolean R_Init( void ) +{ + if( glw_state.initialized ) + return true; + + GL_InitCommands(); + GL_InitRandomTable(); + + // Set screen resolution and fullscreen mode if passed in on command line. + // This is done after executing opengl.cfg, as the command line values should take priority. + SetWidthAndHeightFromCommandLine(); + SetFullscreenModeFromCommandLine(); + + GL_SetDefaultState(); + + // create the window and set up the context + if( !R_Init_Video( )) + { + GL_RemoveCommands(); + R_Free_Video(); + + Sys_Error( "Can't initialize video subsystem\nProbably driver was not installed" ); + return false; + } + + host.renderinfo_changed = false; + r_temppool = Mem_AllocPool( "Render Zone" ); + + GL_SetDefaults(); + R_CheckVBO(); + R_InitImages(); + R_SpriteInit(); + R_StudioInit(); + R_AliasInit(); + R_ClearDecals(); + R_ClearScene(); + + // initialize screen + SCR_Init(); + + return true; +} + +/* +=============== +R_Shutdown +=============== +*/ +void R_Shutdown( void ) +{ + model_t *mod; + int i; + + if( !glw_state.initialized ) + return; + + // release SpriteTextures + for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ ) + { + if( !mod->name[0] ) continue; + Mod_UnloadSpriteModel( mod ); + } + memset( clgame.sprites, 0, sizeof( clgame.sprites )); + + GL_RemoveCommands(); + R_ShutdownImages(); + + Mem_FreePool( &r_temppool ); + + // shut down OS specific OpenGL stuff like contexts, etc. + R_Free_Video(); +} + +/* +================= +GL_ErrorString +convert errorcode to string +================= +*/ +const char *GL_ErrorString( int err ) +{ + switch( err ) + { + case GL_STACK_OVERFLOW: + return "GL_STACK_OVERFLOW"; + case GL_STACK_UNDERFLOW: + return "GL_STACK_UNDERFLOW"; + case GL_INVALID_ENUM: + return "GL_INVALID_ENUM"; + case GL_INVALID_VALUE: + return "GL_INVALID_VALUE"; + case GL_INVALID_OPERATION: + return "GL_INVALID_OPERATION"; + case GL_OUT_OF_MEMORY: + return "GL_OUT_OF_MEMORY"; + default: + return "UNKNOWN ERROR"; + } +} + +/* +================= +GL_CheckForErrors +obsolete +================= +*/ +void GL_CheckForErrors_( const char *filename, const int fileline ) +{ + int err; + + if( !CVAR_TO_BOOL( gl_check_errors )) + return; + + if(( err = pglGetError( )) == GL_NO_ERROR ) + return; + + Con_Printf( S_OPENGL_ERROR "%s (called at %s:%i)\n", GL_ErrorString( err ), filename, fileline ); +} + diff --git a/ref_gl/gl_refrag.c b/ref_gl/gl_refrag.c index da73f149..5e4d4b51 100644 --- a/ref_gl/gl_refrag.c +++ b/ref_gl/gl_refrag.c @@ -13,8 +13,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" -#include "client.h" #include "gl_local.h" #include "mod_local.h" #include "entity_types.h" @@ -161,7 +159,7 @@ void R_AddEfrags( cl_entity_t *ent ) r_emaxs[i] = ent->origin[i] + outmaxs[i]; } - R_SplitEntityOnNode( cl.worldmodel->nodes ); + R_SplitEntityOnNode( WORLDMODEL->nodes ); ent->topnode = r_pefragtopnode; } @@ -206,4 +204,4 @@ void R_StoreEfrags( efrag_t **ppefrag, int framecount ) break; } } -} \ No newline at end of file +} diff --git a/ref_gl/gl_rlight.c b/ref_gl/gl_rlight.c index 0ca73a54..0c451397 100644 --- a/ref_gl/gl_rlight.c +++ b/ref_gl/gl_rlight.c @@ -13,8 +13,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" -#include "client.h" #include "mathlib.h" #include "gl_local.h" #include "pm_local.h" @@ -41,7 +39,7 @@ void CL_RunLightStyles( void ) float scale; lightstyle_t *ls; - if( !cl.worldmodel ) return; + if( !WORLDMODEL ) return; scale = r_lighting_modulate->value; @@ -49,7 +47,7 @@ void CL_RunLightStyles( void ) // 'm' is normal light, 'a' is no light, 'z' is double bright for( i = 0, ls = cl.lightstyles; i < MAX_LIGHTSTYLES; i++, ls++ ) { - if( !cl.worldmodel->lightdata ) + if( !WORLDMODEL->lightdata ) { tr.lightstylevalue[i] = 256 * 256; continue; @@ -388,7 +386,7 @@ colorVec R_LightVecInternal( const vec3_t start, const vec3_t end, vec3_t lspot, if( lspot ) VectorClear( lspot ); if( lvec ) VectorClear( lvec ); - if( cl.worldmodel && cl.worldmodel->lightdata ) + if( WORLDMODEL && WORLDMODEL->lightdata ) { light.r = light.g = light.b = light.a = 0; last_fraction = 1.0f; diff --git a/ref_gl/gl_rmain.c b/ref_gl/gl_rmain.c index 98b25dbe..873d5310 100644 --- a/ref_gl/gl_rmain.c +++ b/ref_gl/gl_rmain.c @@ -13,15 +13,12 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" -#include "client.h" #include "gl_local.h" #include "mathlib.h" #include "library.h" #include "beamdef.h" #include "particledef.h" #include "entity_types.h" -#include "platform/platform.h" #define IsLiquidContents( cnt ) ( cnt == CONTENTS_WATER || cnt == CONTENTS_SLIME || cnt == CONTENTS_LAVA ) @@ -318,8 +315,8 @@ R_GetFarClip */ static float R_GetFarClip( void ) { - if( cl.worldmodel && RI.drawWorld ) - return clgame.movevars.zmax * 1.73f; + if( WORLDMODEL && RI.drawWorld ) + return MOVEVARS->zmax * 1.73f; return 2048.0f; } @@ -475,7 +472,7 @@ R_FindViewLeaf void R_FindViewLeaf( void ) { RI.oldviewleaf = RI.viewleaf; - RI.viewleaf = Mod_PointInLeaf( RI.pvsorigin, cl.worldmodel->nodes ); + RI.viewleaf = Mod_PointInLeaf( RI.pvsorigin, WORLDMODEL->nodes ); } /* @@ -661,7 +658,7 @@ static void R_CheckFog( void ) // quake global fog if( Host_IsQuakeCompatible( )) { - if( !clgame.movevars.fog_settings ) + if( !MOVEVARS->fog_settings ) { if( pglIsEnabled( GL_FOG )) pglDisable( GL_FOG ); @@ -670,10 +667,10 @@ static void R_CheckFog( void ) } // quake-style global fog - RI.fogColor[0] = ((clgame.movevars.fog_settings & 0xFF000000) >> 24) / 255.0f; - RI.fogColor[1] = ((clgame.movevars.fog_settings & 0xFF0000) >> 16) / 255.0f; - RI.fogColor[2] = ((clgame.movevars.fog_settings & 0xFF00) >> 8) / 255.0f; - RI.fogDensity = ((clgame.movevars.fog_settings & 0xFF) / 255.0f) * 0.01f; + RI.fogColor[0] = ((MOVEVARS->fog_settings & 0xFF000000) >> 24) / 255.0f; + RI.fogColor[1] = ((MOVEVARS->fog_settings & 0xFF0000) >> 16) / 255.0f; + RI.fogColor[2] = ((MOVEVARS->fog_settings & 0xFF00) >> 8) / 255.0f; + RI.fogDensity = ((MOVEVARS->fog_settings & 0xFF) / 255.0f) * 0.01f; RI.fogStart = RI.fogEnd = 0.0f; RI.fogColor[3] = 1.0f; RI.fogCustom = false; @@ -855,7 +852,7 @@ void R_DrawEntitiesOnList( void ) if( !RI.onlyClientDraw ) { - CL_DrawBeams( false ); + CL_DrawEFX( tr.frametime, false ); } GL_CheckForErrors(); @@ -913,9 +910,7 @@ void R_DrawEntitiesOnList( void ) if( !RI.onlyClientDraw ) { R_AllowFog( false ); - CL_DrawBeams( true ); - CL_DrawParticles( tr.frametime ); - CL_DrawTracers( tr.frametime ); + CL_DrawEFX( tr.frametime, true ); R_AllowFog( true ); } @@ -939,7 +934,7 @@ R_SetupRefParams must be called right before */ void R_RenderScene( void ) { - if( !cl.worldmodel && RI.drawWorld ) + if( !WORLDMODEL && RI.drawWorld ) Host_Error( "R_RenderView: NULL worldmodel\n" ); // frametime is valid only for normal pass @@ -985,7 +980,7 @@ qboolean R_DoResetGamma( void ) { // FIXME: this looks ugly. apply the backward gamma changes to the output image return false; - +#if 0 switch( cls.scrshot_action ) { case scrshot_normal: @@ -1005,6 +1000,7 @@ qboolean R_DoResetGamma( void ) default: return false; } +#endif } /* @@ -1222,7 +1218,7 @@ static int GL_RenderGetParm( int parm, int arg ) arg = bound( 0, arg, MAX_LIGHTMAPS - 1 ); return tr.lightmapTextures[arg]; case PARM_SKY_SPHERE: - return FBitSet( world.flags, FWORLD_SKYSPHERE ) && !FBitSet( world.flags, FWORLD_CUSTOM_SKYBOX ); + return FBitSet( WORLDMODEL->flags, FWORLD_SKYSPHERE ) && !FBitSet( WORLDMODEL->flags, FWORLD_CUSTOM_SKYBOX ); case PARAM_GAMEPAUSED: return cl.paused; case PARM_WIDESCREEN: @@ -1254,7 +1250,7 @@ static int GL_RenderGetParm( int parm, int arg ) arg = bound( 0, arg, MAX_LIGHTSTYLES - 1 ); return tr.lightstylevalue[arg]; case PARM_MAP_HAS_DELUXE: - return FBitSet( world.flags, FWORLD_HAS_DELUXEMAP ); + return FBitSet( WORLDMODEL->flags, FWORLD_HAS_DELUXEMAP ); case PARM_MAX_IMAGE_UNITS: return GL_MaxTextureUnits(); case PARM_CLIENT_ACTIVE: @@ -1264,8 +1260,8 @@ static int GL_RenderGetParm( int parm, int arg ) case PARM_DEDICATED_SERVER: return (host.type == HOST_DEDICATED); case PARM_SURF_SAMPLESIZE: - if( arg >= 0 && arg < cl.worldmodel->numsurfaces ) - return Mod_SampleSizeForFace( &cl.worldmodel->surfaces[arg] ); + if( arg >= 0 && arg < WORLDMODEL->numsurfaces ) + return Mod_SampleSizeForFace( &WORLDMODEL->surfaces[arg] ); return LM_SAMPLE_SIZE; case PARM_GL_CONTEXT_TYPE: return glConfig.context; @@ -1274,7 +1270,7 @@ static int GL_RenderGetParm( int parm, int arg ) case PARM_STENCIL_ACTIVE: return glState.stencilEnabled; case PARM_WATER_ALPHA: - return FBitSet( world.flags, FWORLD_WATERALPHA ); + return FBitSet( WORLDMODEL->flags, FWORLD_WATERALPHA ); } return 0; } @@ -1352,9 +1348,12 @@ static void R_SetCurrentModel( model_t *mod ) RI.currentmodel = mod; } +// to engine? +#if 0 + static int R_FatPVS( const vec3_t org, float radius, byte *visbuffer, qboolean merge, qboolean fullvis ) { - return Mod_FatPVS( org, radius, visbuffer, world.visbytes, merge, fullvis ); + return Mod_FatPVS( org, radius, visbuffer, WORLDMODEL->visbytes, merge, fullvis ); } static lightstyle_t *CL_GetLightStyle( int number ) @@ -1458,9 +1457,11 @@ const char *CL_GenericHandle( int fileindex ) return 0; return cl.files_precache[fileindex]; } +#endif static render_api_t gRenderAPI = { +#if 0 GL_RenderGetParm, R_GetDetailScaleForTexture, R_GetExtraParmsForTexture, @@ -1526,6 +1527,7 @@ static render_api_t gRenderAPI = Cvar_Set, S_FadeMusicVolume, COM_SetRandomSeed, +#endif }; /* diff --git a/ref_gl/gl_rmath.c b/ref_gl/gl_rmath.c index 90679250..d8aee626 100644 --- a/ref_gl/gl_rmath.c +++ b/ref_gl/gl_rmath.c @@ -13,10 +13,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" #include "gl_local.h" #include "mathlib.h" -#include "client.h" /* ======================================================================== diff --git a/ref_gl/gl_rmisc.c b/ref_gl/gl_rmisc.c index 8ac4a638..b0b64168 100644 --- a/ref_gl/gl_rmisc.c +++ b/ref_gl/gl_rmisc.c @@ -13,8 +13,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" -#include "client.h" #include "gl_local.h" #include "mod_local.h" #include "shake.h" @@ -79,9 +77,9 @@ static void R_ParseDetailTextures( const char *filename ) continue; // search for existing texture and uploading detail texture - for( i = 0; i < cl.worldmodel->numtextures; i++ ) + for( i = 0; i < WORLDMODEL->numtextures; i++ ) { - tex = cl.worldmodel->textures[i]; + tex = WORLDMODEL->textures[i]; if( Q_stricmp( tex->name, texname )) continue; @@ -116,7 +114,7 @@ void R_NewMap( void ) { string mapname, filepath; - Q_strncpy( mapname, cl.worldmodel->name, sizeof( mapname )); + Q_strncpy( mapname, WORLDMODEL->name, sizeof( mapname )); COM_StripExtension( mapname ); Q_sprintf( filepath, "%s_detail.txt", mapname ); @@ -152,20 +150,20 @@ void R_NewMap( void ) } // clear out efrags in case the level hasn't been reloaded - for( i = 0; i < cl.worldmodel->numleafs; i++ ) - cl.worldmodel->leafs[i+1].efrags = NULL; + for( i = 0; i < WORLDMODEL->numleafs; i++ ) + WORLDMODEL->leafs[i+1].efrags = NULL; tr.skytexturenum = -1; tr.max_recursion = 0; pglDisable( GL_FOG ); // clearing texture chains - for( i = 0; i < cl.worldmodel->numtextures; i++ ) + for( i = 0; i < WORLDMODEL->numtextures; i++ ) { - if( !cl.worldmodel->textures[i] ) + if( !WORLDMODEL->textures[i] ) continue; - tx = cl.worldmodel->textures[i]; + tx = WORLDMODEL->textures[i]; if( !Q_strncmp( tx->name, "sky", 3 ) && tx->width == ( tx->height * 2 )) tr.skytexturenum = i; @@ -173,7 +171,7 @@ void R_NewMap( void ) tx->texturechain = NULL; } - R_SetupSky( clgame.movevars.skyName ); + R_SetupSky( MOVEVARS->skyName ); GL_BuildLightmaps (); R_GenerateVBO(); diff --git a/ref_gl/gl_rpart.c b/ref_gl/gl_rpart.c index e6e070e0..d6b4b106 100644 --- a/ref_gl/gl_rpart.c +++ b/ref_gl/gl_rpart.c @@ -13,8 +13,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" -#include "client.h" #include "gl_local.h" #include "r_efx.h" #include "event_flags.h" @@ -24,330 +22,6 @@ GNU General Public License for more details. #include "cl_tent.h" #include "studio.h" -#define PART_SIZE Q_max( 0.5f, cl_draw_particles->value ) - -/* -============================================================== - -PARTICLES MANAGEMENT - -============================================================== -*/ -// particle ramps -static int ramp1[8] = { 0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61 }; -static int ramp2[8] = { 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66 }; -static int ramp3[6] = { 0x6d, 0x6b, 6, 5, 4, 3 }; -static float gTracerSize[11] = { 1.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; -static int gSparkRamp[9] = { 0xfe, 0xfd, 0xfc, 0x6f, 0x6e, 0x6d, 0x6c, 0x67, 0x60 }; - -static color24 gTracerColors[] = -{ -{ 255, 255, 255 }, // White -{ 255, 0, 0 }, // Red -{ 0, 255, 0 }, // Green -{ 0, 0, 255 }, // Blue -{ 0, 0, 0 }, // Tracer default, filled in from cvars, etc. -{ 255, 167, 17 }, // Yellow-orange sparks -{ 255, 130, 90 }, // Yellowish streaks (garg) -{ 55, 60, 144 }, // Blue egon streak -{ 255, 130, 90 }, // More Yellowish streaks (garg) -{ 255, 140, 90 }, // More Yellowish streaks (garg) -{ 200, 130, 90 }, // More red streaks (garg) -{ 255, 120, 70 }, // Darker red streaks (garg) -}; - -convar_t *tracerred; -convar_t *tracergreen; -convar_t *tracerblue; -convar_t *traceralpha; -convar_t *tracerspeed; -convar_t *tracerlength; -convar_t *traceroffset; - -particle_t *cl_active_particles; -particle_t *cl_active_tracers; -particle_t *cl_free_particles; -particle_t *cl_particles = NULL; // particle pool -static vec3_t cl_avelocities[NUMVERTEXNORMALS]; -static float cl_lasttimewarn = 0.0f; - -/* -================ -R_LookupColor - -find nearest color in particle palette -================ -*/ -short R_LookupColor( byte r, byte g, byte b ) -{ - int i, best; - float diff, bestdiff; - float rf, gf, bf; - - bestdiff = 999999; - best = 65535; - - for( i = 0; i < 256; i++ ) - { - rf = r - clgame.palette[i].r; - gf = g - clgame.palette[i].g; - bf = b - clgame.palette[i].b; - - // convert color to monochrome - diff = rf * (rf * 0.2) + gf * (gf * 0.5) + bf * (bf * 0.3); - - if ( diff < bestdiff ) - { - bestdiff = diff; - best = i; - } - } - - return best; -} - -/* -================ -R_GetPackedColor - -in hardware mode does nothing -================ -*/ -void R_GetPackedColor( short *packed, short color ) -{ - if( packed ) *packed = 0; -} - -/* -================ -CL_InitParticles - -================ -*/ -void CL_InitParticles( void ) -{ - int i; - - cl_particles = Mem_Calloc( cls.mempool, sizeof( particle_t ) * GI->max_particles ); - CL_ClearParticles (); - - // this is used for EF_BRIGHTFIELD - for( i = 0; i < NUMVERTEXNORMALS; i++ ) - { - cl_avelocities[i][0] = COM_RandomFloat( 0.0f, 2.55f ); - cl_avelocities[i][1] = COM_RandomFloat( 0.0f, 2.55f ); - cl_avelocities[i][2] = COM_RandomFloat( 0.0f, 2.55f ); - } - - tracerred = Cvar_Get( "tracerred", "0.8", 0, "tracer red component weight ( 0 - 1.0 )" ); - tracergreen = Cvar_Get( "tracergreen", "0.8", 0, "tracer green component weight ( 0 - 1.0 )" ); - tracerblue = Cvar_Get( "tracerblue", "0.4", 0, "tracer blue component weight ( 0 - 1.0 )" ); - traceralpha = Cvar_Get( "traceralpha", "0.5", 0, "tracer alpha amount ( 0 - 1.0 )" ); - tracerspeed = Cvar_Get( "tracerspeed", "6000", 0, "tracer speed" ); - tracerlength = Cvar_Get( "tracerlength", "0.8", 0, "tracer length factor" ); - traceroffset = Cvar_Get( "traceroffset", "30", 0, "tracer starting offset" ); -} - -/* -================ -CL_ClearParticles - -================ -*/ -void CL_ClearParticles( void ) -{ - int i; - - if( !cl_particles ) return; - - cl_free_particles = cl_particles; - cl_active_particles = NULL; - cl_active_tracers = NULL; - - for( i = 0; i < GI->max_particles - 1; i++ ) - cl_particles[i].next = &cl_particles[i+1]; - - cl_particles[GI->max_particles-1].next = NULL; -} - -/* -================ -CL_FreeParticles - -================ -*/ -void CL_FreeParticles( void ) -{ - if( cl_particles ) - Mem_Free( cl_particles ); - cl_particles = NULL; -} - -/* -================ -CL_FreeParticle - -move particle to freelist -================ -*/ -void CL_FreeParticle( particle_t *p ) -{ - if( p->deathfunc ) - { - // call right the deathfunc before die - p->deathfunc( p ); - p->deathfunc = NULL; - } - - p->next = cl_free_particles; - cl_free_particles = p; -} - -/* -================ -R_AllocParticle - -can return NULL if particles is out -================ -*/ -particle_t *R_AllocParticle( void (*callback)( particle_t*, float )) -{ - particle_t *p; - - if( !cl_draw_particles->value ) - return NULL; - - // never alloc particles when we not in game - if( tr.frametime == 0.0 ) return NULL; - - if( !cl_free_particles ) - { - if( cl_lasttimewarn < host.realtime ) - { - // don't spam about overflow - Con_DPrintf( S_ERROR "Overflow %d particles\n", GI->max_particles ); - cl_lasttimewarn = host.realtime + 1.0f; - } - return NULL; - } - - p = cl_free_particles; - cl_free_particles = p->next; - p->next = cl_active_particles; - cl_active_particles = p; - - // clear old particle - p->type = pt_static; - VectorClear( p->vel ); - VectorClear( p->org ); - p->packedColor = 0; - p->die = cl.time; - p->color = 0; - p->ramp = 0; - - if( callback ) - { - p->type = pt_clientcustom; - p->callback = callback; - } - - return p; -} - -/* -================ -R_AllocTracer - -can return NULL if particles is out -================ -*/ -particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life ) -{ - particle_t *p; - - if( !cl_draw_tracers->value ) - return NULL; - - // never alloc particles when we not in game - if( tr.frametime == 0.0 ) return NULL; - - if( !cl_free_particles ) - { - if( cl_lasttimewarn < host.realtime ) - { - // don't spam about overflow - Con_DPrintf( S_ERROR "Overflow %d tracers\n", GI->max_particles ); - cl_lasttimewarn = host.realtime + 1.0f; - } - return NULL; - } - - p = cl_free_particles; - cl_free_particles = p->next; - p->next = cl_active_tracers; - cl_active_tracers = p; - - // clear old particle - p->type = pt_static; - VectorCopy( org, p->org ); - VectorCopy( vel, p->vel ); - p->die = cl.time + life; - p->ramp = tracerlength->value; - p->color = 4; // select custom color - p->packedColor = 255; // alpha - - return p; -} - -/* -============== -R_FreeDeadParticles - -Free particles that time has expired -============== -*/ -void R_FreeDeadParticles( particle_t **ppparticles ) -{ - particle_t *p, *kill; - - // kill all the ones hanging direcly off the base pointer - while( 1 ) - { - kill = *ppparticles; - if( kill && kill->die < cl.time ) - { - if( kill->deathfunc ) - kill->deathfunc( kill ); - kill->deathfunc = NULL; - *ppparticles = kill->next; - kill->next = cl_free_particles; - cl_free_particles = kill; - continue; - } - break; - } - - // kill off all the others - for( p = *ppparticles; p; p = p->next ) - { - while( 1 ) - { - kill = p->next; - if( kill && kill->die < cl.time ) - { - if( kill->deathfunc ) - kill->deathfunc( kill ); - kill->deathfunc = NULL; - p->next = kill->next; - kill->next = cl_free_particles; - cl_free_particles = kill; - continue; - } - break; - } - } -} - /* ================ CL_DrawParticles @@ -355,14 +29,14 @@ CL_DrawParticles update particle color, position, free expired and draw it ================ */ -void CL_DrawParticles( double frametime ) +void CL_DrawParticles( double frametime, particle_t *cl_active_particles ) { particle_t *p; float time3 = 15.0f * frametime; float time2 = 10.0f * frametime; float time1 = 5.0f * frametime; float dvel = 4.0f * frametime; - float grav = frametime * clgame.movevars.gravity * 0.05f; + float grav = frametime * MOVEVARS->gravity * 0.05f; vec3_t right, up; color24 *pColor; int alpha; @@ -371,8 +45,6 @@ void CL_DrawParticles( double frametime ) if( !cl_draw_particles->value ) return; - R_FreeDeadParticles( &cl_active_particles ); - if( !cl_active_particles ) return; // nothing to draw? @@ -547,7 +219,7 @@ CL_DrawTracers update tracer color, position, free expired and draw it ================ */ -void CL_DrawTracers( double frametime ) +void CL_DrawTracers( double frametime, particle_t *cl_active_tracers ) { float scale, atten, gravity; vec3_t screenLast, screen; @@ -569,8 +241,6 @@ void CL_DrawTracers( double frametime ) ClearBits( traceralpha->flags, FCVAR_CHANGED ); } - R_FreeDeadParticles( &cl_active_tracers ); - if( !cl_active_tracers ) return; // nothing to draw? @@ -582,7 +252,7 @@ void CL_DrawTracers( double frametime ) pglDisable( GL_ALPHA_TEST ); pglDepthMask( GL_FALSE ); - gravity = frametime * clgame.movevars.gravity; + gravity = frametime * MOVEVARS->gravity; scale = 1.0 - (frametime * 0.9); if( scale < 0.0f ) scale = 0.0f; @@ -676,989 +346,11 @@ void CL_DrawParticlesExternal( const ref_viewpass_t *rvp, qboolean trans_pass, f R_SetupGL( false ); // don't touch GL-states // setup PVS for frame - memcpy( RI.visbytes, tr.visbytes, world.visbytes ); + memcpy( RI.visbytes, tr.visbytes, WORLDMODEL->visbytes ); tr.frametime = frametime; - if( trans_pass == false ) - { - CL_DrawBeams( false ); - } - else - { - CL_DrawBeams( true ); - CL_DrawParticles( tr.frametime ); - CL_DrawTracers( tr.frametime ); - } + CL_DrawEFX( frametime, trans_pass ); // restore internal state memcpy( &RI, &oldRI, sizeof( ref_instance_t )); } - -/* -=============== -R_EntityParticles - -set EF_BRIGHTFIELD effect -=============== -*/ -void R_EntityParticles( cl_entity_t *ent ) -{ - float angle; - float sr, sp, sy, cr, cp, cy; - vec3_t forward; - particle_t *p; - int i; - - for( i = 0; i < NUMVERTEXNORMALS; i++ ) - { - p = R_AllocParticle( NULL ); - if( !p ) return; - - angle = cl.time * cl_avelocities[i][0]; - SinCos( angle, &sy, &cy ); - angle = cl.time * cl_avelocities[i][1]; - SinCos( angle, &sp, &cp ); - angle = cl.time * cl_avelocities[i][2]; - SinCos( angle, &sr, &cr ); - - VectorSet( forward, cp * cy, cp * sy, -sp ); - - p->die = cl.time + 0.001f; - p->color = 111; // yellow - - VectorMAMAM( 1.0f, ent->origin, 64.0f, m_bytenormals[i], 16.0f, forward, p->org ); - } -} - -/* -=============== -R_ParticleExplosion - -=============== -*/ -void R_ParticleExplosion( const vec3_t org ) -{ - particle_t *p; - int i, j; - - for( i = 0; i < 1024; i++ ) - { - p = R_AllocParticle( NULL ); - if( !p ) return; - - p->die = cl.time + 5.0f; - p->ramp = COM_RandomLong( 0, 3 ); - p->color = ramp1[0]; - - for( j = 0; j < 3; j++ ) - { - p->org[j] = org[j] + COM_RandomFloat( -16.0f, 16.0f ); - p->vel[j] = COM_RandomFloat( -256.0f, 256.0f ); - } - - if( i & 1 ) p->type = pt_explode; - else p->type = pt_explode2; - } -} - -/* -=============== -R_ParticleExplosion2 - -=============== -*/ -void R_ParticleExplosion2( const vec3_t org, int colorStart, int colorLength ) -{ - int i, j; - int colorMod = 0; - particle_t *p; - - for( i = 0; i < 512; i++ ) - { - p = R_AllocParticle( NULL ); - if( !p ) return; - - p->die = cl.time + 0.3f; - p->color = colorStart + ( colorMod % colorLength ); - p->packedColor = 255; // use old code for blob particles - colorMod++; - - p->type = pt_blob; - - for( j = 0; j < 3; j++ ) - { - p->org[j] = org[j] + COM_RandomFloat( -16.0f, 16.0f ); - p->vel[j] = COM_RandomFloat( -256.0f, 256.0f ); - } - } -} - -/* -=============== -R_BlobExplosion - -=============== -*/ -void R_BlobExplosion( const vec3_t org ) -{ - particle_t *p; - int i, j; - - for( i = 0; i < 1024; i++ ) - { - p = R_AllocParticle( NULL ); - if( !p ) return; - - p->die = cl.time + COM_RandomFloat( 2.0f, 2.4f ); - p->packedColor = 255; // use old code for blob particles - - if( i & 1 ) - { - p->type = pt_blob; - p->color = COM_RandomLong( 66, 71 ); - } - else - { - p->type = pt_blob2; - p->color = COM_RandomLong( 150, 155 ); - } - - for( j = 0; j < 3; j++ ) - { - p->org[j] = org[j] + COM_RandomFloat( -16.0f, 16.0f ); - p->vel[j] = COM_RandomFloat( -256.0f, 256.0f ); - } - } -} - -/* -=============== -ParticleEffect - -PARTICLE_EFFECT on server -=============== -*/ -void R_RunParticleEffect( const vec3_t org, const vec3_t dir, int color, int count ) -{ - particle_t *p; - int i; - - if( count == 1024 ) - { - // rocket explosion - R_ParticleExplosion( org ); - return; - } - - for( i = 0; i < count; i++ ) - { - p = R_AllocParticle( NULL ); - if( !p ) return; - - p->color = (color & ~7) + COM_RandomLong( 0, 7 ); - p->die = cl.time + COM_RandomFloat( 0.1f, 0.4f ); - p->type = pt_slowgrav; - - VectorAddScalar( org, COM_RandomFloat( -8.0f, 8.0f ), p->org ); - VectorScale( dir, 15.0f, p->vel ); - } -} - -/* -=============== -R_Blood - -particle spray -=============== -*/ -void R_Blood( const vec3_t org, const vec3_t ndir, int pcolor, int speed ) -{ - vec3_t pos, dir, vec; - float pspeed = speed * 3.0f; - int i, j; - particle_t *p; - - VectorNormalize2( ndir, dir ); - - for( i = 0; i < (speed / 2); i++ ) - { - VectorAddScalar( org, COM_RandomFloat( -3.0f, 3.0f ), pos ); - VectorAddScalar( dir, COM_RandomFloat( -0.06f, 0.06f ), vec ); - - for( j = 0; j < 7; j++ ) - { - p = R_AllocParticle( NULL ); - if( !p ) return; - - p->die = cl.time + 1.5f; - p->color = pcolor + COM_RandomLong( 0, 9 ); - p->type = pt_vox_grav; - - VectorAddScalar( pos, COM_RandomFloat( -1.0f, 1.0f ), p->org ); - VectorScale( vec, pspeed, p->vel ); - } - } -} - -/* -=============== -R_BloodStream - -particle spray 2 -=============== -*/ -void R_BloodStream( const vec3_t org, const vec3_t dir, int pcolor, int speed ) -{ - particle_t *p; - int i, j; - float arc; - float accel = speed; - - for( arc = 0.05f, i = 0; i < 100; i++ ) - { - p = R_AllocParticle( NULL ); - if( !p ) return; - - p->die = cl.time + 2.0f; - p->type = pt_vox_grav; - p->color = pcolor + COM_RandomLong( 0, 9 ); - - VectorCopy( org, p->org ); - VectorCopy( dir, p->vel ); - - p->vel[2] -= arc; - arc -= 0.005f; - VectorScale( p->vel, accel, p->vel ); - accel -= 0.00001f; // so last few will drip - } - - for( arc = 0.075f, i = 0; i < ( speed / 5 ); i++ ) - { - float num; - - p = R_AllocParticle( NULL ); - if( !p ) return; - - p->die = cl.time + 3.0f; - p->color = pcolor + COM_RandomLong( 0, 9 ); - p->type = pt_vox_slowgrav; - - VectorCopy( org, p->org ); - VectorCopy( dir, p->vel ); - - p->vel[2] -= arc; - arc -= 0.005f; - - num = COM_RandomFloat( 0.0f, 1.0f ); - accel = speed * num; - num *= 1.7f; - - VectorScale( p->vel, num, p->vel ); - VectorScale( p->vel, accel, p->vel ); - - for( j = 0; j < 2; j++ ) - { - p = R_AllocParticle( NULL ); - if( !p ) return; - - p->die = cl.time + 3.0f; - p->color = pcolor + COM_RandomLong( 0, 9 ); - p->type = pt_vox_slowgrav; - - p->org[0] = org[0] + COM_RandomFloat( -1.0f, 1.0f ); - p->org[1] = org[1] + COM_RandomFloat( -1.0f, 1.0f ); - p->org[2] = org[2] + COM_RandomFloat( -1.0f, 1.0f ); - - VectorCopy( dir, p->vel ); - p->vel[2] -= arc; - - VectorScale( p->vel, num, p->vel ); - VectorScale( p->vel, accel, p->vel ); - } - } -} - -/* -=============== -R_LavaSplash - -=============== -*/ -void R_LavaSplash( const vec3_t org ) -{ - particle_t *p; - float vel; - vec3_t dir; - int i, j, k; - - for( i = -16; i < 16; i++ ) - { - for( j = -16; j <16; j++ ) - { - for( k = 0; k < 1; k++ ) - { - p = R_AllocParticle( NULL ); - if( !p ) return; - - p->die = cl.time + COM_RandomFloat( 2.0f, 2.62f ); - p->color = COM_RandomLong( 224, 231 ); - p->type = pt_slowgrav; - - dir[0] = j * 8.0f + COM_RandomFloat( 0.0f, 7.0f ); - dir[1] = i * 8.0f + COM_RandomFloat( 0.0f, 7.0f ); - dir[2] = 256.0f; - - p->org[0] = org[0] + dir[0]; - p->org[1] = org[1] + dir[1]; - p->org[2] = org[2] + COM_RandomFloat( 0.0f, 63.0f ); - - VectorNormalize( dir ); - vel = COM_RandomFloat( 50.0f, 113.0f ); - VectorScale( dir, vel, p->vel ); - } - } - } -} - -/* -=============== -R_ParticleBurst - -=============== -*/ -void R_ParticleBurst( const vec3_t org, int size, int color, float life ) -{ - particle_t *p; - vec3_t dir, dest; - int i, j; - float dist; - - for( i = 0; i < 32; i++ ) - { - for( j = 0; j < 32; j++ ) - { - p = R_AllocParticle( NULL ); - if( !p ) return; - - p->die = cl.time + life + COM_RandomFloat( -0.5f, 0.5f ); - p->color = color + COM_RandomLong( 0, 10 ); - p->ramp = 1.0f; - - VectorCopy( org, p->org ); - VectorAddScalar( org, COM_RandomFloat( -size, size ), dest ); - VectorSubtract( dest, p->org, dir ); - dist = VectorNormalizeLength( dir ); - VectorScale( dir, ( dist / life ), p->vel ); - } - } -} - -/* -=============== -R_LargeFunnel - -=============== -*/ -void R_LargeFunnel( const vec3_t org, int reverse ) -{ - particle_t *p; - float vel, dist; - vec3_t dir, dest; - int i, j; - - for( i = -8; i < 8; i++ ) - { - for( j = -8; j < 8; j++ ) - { - p = R_AllocParticle( NULL ); - if( !p ) return; - - dest[0] = (i * 32.0f) + org[0]; - dest[1] = (j * 32.0f) + org[1]; - dest[2] = org[2] + COM_RandomFloat( 100.0f, 800.0f ); - - if( reverse ) - { - VectorCopy( org, p->org ); - VectorSubtract( dest, p->org, dir ); - } - else - { - VectorCopy( dest, p->org ); - VectorSubtract( org, p->org, dir ); - } - - vel = dest[2] / 8.0f; - if( vel < 64.0f ) vel = 64.0f; - - dist = VectorNormalizeLength( dir ); - vel += COM_RandomFloat( 64.0f, 128.0f ); - VectorScale( dir, vel, p->vel ); - p->die = cl.time + (dist / vel ); - p->color = 244; // green color - } - } -} - -/* -=============== -R_TeleportSplash - -=============== -*/ -void R_TeleportSplash( const vec3_t org ) -{ - particle_t *p; - vec3_t dir; - float vel; - int i, j, k; - - for( i = -16; i < 16; i += 4 ) - { - for( j = -16; j < 16; j += 4 ) - { - for( k = -24; k < 32; k += 4 ) - { - p = R_AllocParticle( NULL ); - if( !p ) return; - - p->die = cl.time + COM_RandomFloat( 0.2f, 0.34f ); - p->color = COM_RandomLong( 7, 14 ); - p->type = pt_slowgrav; - - dir[0] = j * 8.0f; - dir[1] = i * 8.0f; - dir[2] = k * 8.0f; - - p->org[0] = org[0] + i + COM_RandomFloat( 0.0f, 3.0f ); - p->org[1] = org[1] + j + COM_RandomFloat( 0.0f, 3.0f ); - p->org[2] = org[2] + k + COM_RandomFloat( 0.0f, 3.0f ); - - VectorNormalize( dir ); - vel = COM_RandomFloat( 50.0f, 113.0f ); - VectorScale( dir, vel, p->vel ); - } - } - } -} - -/* -=============== -R_RocketTrail - -=============== -*/ -void R_RocketTrail( vec3_t start, vec3_t end, int type ) -{ - vec3_t vec, right, up; - static int tracercount; - float s, c, x, y; - float len, dec; - particle_t *p; - - VectorSubtract( end, start, vec ); - len = VectorNormalizeLength( vec ); - - if( type == 7 ) - { - VectorVectors( vec, right, up ); - } - - if( type < 128 ) - { - dec = 3.0f; - } - else - { - dec = 1.0f; - type -= 128; - } - - VectorScale( vec, dec, vec ); - - while( len > 0 ) - { - len -= dec; - - p = R_AllocParticle( NULL ); - if( !p ) return; - - p->die = cl.time + 2.0f; - - switch( type ) - { - case 0: // rocket trail - p->ramp = COM_RandomLong( 0, 3 ); - p->color = ramp3[(int)p->ramp]; - p->type = pt_fire; - VectorAddScalar( start, COM_RandomFloat( -3.0f, 3.0f ), p->org ); - break; - case 1: // smoke smoke - p->ramp = COM_RandomLong( 2, 5 ); - p->color = ramp3[(int)p->ramp]; - p->type = pt_fire; - VectorAddScalar( start, COM_RandomFloat( -3.0f, 3.0f ), p->org ); - break; - case 2: // blood - p->type = pt_grav; - p->color = COM_RandomLong( 67, 74 ); - VectorAddScalar( start, COM_RandomFloat( -3.0f, 3.0f ), p->org ); - break; - case 3: - case 5: // tracer - p->die = cl.time + 0.5f; - - if( type == 3 ) p->color = 52 + (( tracercount & 4 )<<1 ); - else p->color = 230 + (( tracercount & 4 )<<1 ); - - VectorCopy( start, p->org ); - tracercount++; - - if( FBitSet( tracercount, 1 )) - { - p->vel[0] = 30.0f * vec[1]; - p->vel[1] = 30.0f * -vec[0]; - } - else - { - p->vel[0] = 30.0f * -vec[1]; - p->vel[1] = 30.0f * vec[0]; - } - break; - case 4: // slight blood - p->type = pt_grav; - p->color = COM_RandomLong( 67, 70 ); - VectorAddScalar( start, COM_RandomFloat( -3.0f, 3.0f ), p->org ); - len -= 3.0f; - break; - case 6: // voor trail - p->color = COM_RandomLong( 152, 155 ); - p->die += 0.3f; - VectorAddScalar( start, COM_RandomFloat( -8.0f, 8.0f ), p->org ); - break; - case 7: // explosion tracer - x = COM_RandomLong( 0, 65535 ); - y = COM_RandomLong( 8, 16 ); - SinCos( x, &s, &c ); - s *= y; - c *= y; - - VectorMAMAM( 1.0f, start, s, right, c, up, p->org ); - VectorSubtract( start, p->org, p->vel ); - VectorScale( p->vel, 2.0f, p->vel ); - VectorMA( p->vel, COM_RandomFloat( 96.0f, 111.0f ), vec, p->vel ); - p->ramp = COM_RandomLong( 0, 3 ); - p->color = ramp3[(int)p->ramp]; - p->type = pt_explode2; - break; - default: - // just build line to show error - VectorCopy( start, p->org ); - break; - } - - VectorAdd( start, vec, start ); - } -} - -/* -================ -R_ParticleLine - -================ -*/ -void R_ParticleLine( const vec3_t start, const vec3_t end, byte r, byte g, byte b, float life ) -{ - int pcolor; - - pcolor = R_LookupColor( r, g, b ); - PM_ParticleLine( start, end, pcolor, life, 0 ); -} - -/* -================ -R_ParticleBox - -================ -*/ -void R_ParticleBox( const vec3_t absmin, const vec3_t absmax, byte r, byte g, byte b, float life ) -{ - vec3_t mins, maxs; - vec3_t origin; - int pcolor; - - pcolor = R_LookupColor( r, g, b ); - - VectorAverage( absmax, absmin, origin ); - VectorSubtract( absmax, origin, maxs ); - VectorSubtract( absmin, origin, mins ); - - PM_DrawBBox( mins, maxs, origin, pcolor, life ); -} - -/* -================ -R_ShowLine - -================ -*/ -void R_ShowLine( const vec3_t start, const vec3_t end ) -{ - vec3_t dir, org; - float len; - particle_t *p; - - VectorSubtract( end, start, dir ); - len = VectorNormalizeLength( dir ); - VectorScale( dir, 5.0f, dir ); - VectorCopy( start, org ); - - while( len > 0 ) - { - len -= 5.0f; - - p = R_AllocParticle( NULL ); - if( !p ) return; - - p->die = cl.time + 30; - p->color = 75; - - VectorCopy( org, p->org ); - VectorAdd( org, dir, org ); - } -} - -/* -=============== -R_BulletImpactParticles - -=============== -*/ -void R_BulletImpactParticles( const vec3_t pos ) -{ - int i, quantity; - int color; - float dist; - vec3_t dir; - particle_t *p; - - VectorSubtract( pos, RI.vieworg, dir ); - dist = VectorLength( dir ); - if( dist > 1000.0f ) dist = 1000.0f; - - quantity = (1000.0f - dist) / 100.0f; - if( quantity == 0 ) quantity = 1; - - color = 3 - ((30 * quantity) / 100 ); - R_SparkStreaks( pos, 2, -200, 200 ); - - for( i = 0; i < quantity * 4; i++ ) - { - p = R_AllocParticle( NULL ); - if( !p ) return; - - VectorCopy( pos, p->org); - - p->vel[0] = COM_RandomFloat( -1.0f, 1.0f ); - p->vel[1] = COM_RandomFloat( -1.0f, 1.0f ); - p->vel[2] = COM_RandomFloat( -1.0f, 1.0f ); - VectorScale( p->vel, COM_RandomFloat( 50.0f, 100.0f ), p->vel ); - - p->die = cl.time + 0.5; - p->color = 3 - color; - p->type = pt_grav; - } -} - -/* -=============== -R_FlickerParticles - -=============== -*/ -void R_FlickerParticles( const vec3_t org ) -{ - particle_t *p; - int i; - - for( i = 0; i < 15; i++ ) - { - p = R_AllocParticle( NULL ); - if( !p ) return; - - VectorCopy( org, p->org ); - p->vel[0] = COM_RandomFloat( -32.0f, 32.0f ); - p->vel[1] = COM_RandomFloat( -32.0f, 32.0f ); - p->vel[2] = COM_RandomFloat( 80.0f, 143.0f ); - - p->die = cl.time + 2.0f; - p->type = pt_blob2; - p->color = 254; - } -} - -/* -=============== -R_StreakSplash - -create a splash of streaks -=============== -*/ -void R_StreakSplash( const vec3_t pos, const vec3_t dir, int color, int count, float speed, int velocityMin, int velocityMax ) -{ - vec3_t vel, vel2; - particle_t *p; - int i; - - VectorScale( dir, speed, vel ); - - for( i = 0; i < count; i++ ) - { - VectorAddScalar( vel, COM_RandomFloat( velocityMin, velocityMax ), vel2 ); - p = R_AllocTracer( pos, vel2, COM_RandomFloat( 0.1f, 0.5f )); - if( !p ) return; - - p->type = pt_grav; - p->color = color; - p->ramp = 1.0f; - } -} - -/* -=============== -R_DebugParticle - -just for debug purposes -=============== -*/ -void R_DebugParticle( const vec3_t pos, byte r, byte g, byte b ) -{ - particle_t *p; - - p = R_AllocParticle( NULL ); - if( !p ) return; - - VectorCopy( pos, p->org ); - p->color = R_LookupColor( r, g, b ); - p->die = cl.time + 0.01f; -} - -/* -=============== -CL_Particle - -pmove debugging particle -=============== -*/ -void CL_Particle( const vec3_t org, int color, float life, int zpos, int zvel ) -{ - particle_t *p; - - p = R_AllocParticle( NULL ); - if( !p ) return; - - if( org ) VectorCopy( org, p->org ); - p->die = cl.time + life; - p->vel[2] += zvel; // ??? - p->color = color; -} - -/* -=============== -R_TracerEffect - -=============== -*/ -void R_TracerEffect( const vec3_t start, const vec3_t end ) -{ - vec3_t pos, vel, dir; - float len, speed; - float offset; - - speed = Q_max( tracerspeed->value, 3.0f ); - - VectorSubtract( end, start, dir ); - len = VectorLength( dir ); - if( len == 0.0f ) return; - - VectorScale( dir, 1.0f / len, dir ); // normalize - offset = COM_RandomFloat( -10.0f, 9.0f ) + traceroffset->value; - VectorScale( dir, offset, vel ); - VectorAdd( start, vel, pos ); - VectorScale( dir, speed, vel ); - - R_AllocTracer( pos, vel, len / speed ); -} - -/* -=============== -R_UserTracerParticle - -=============== -*/ -void R_UserTracerParticle( float *org, float *vel, float life, int colorIndex, float length, byte deathcontext, void (*deathfunc)( particle_t *p )) -{ - particle_t *p; - - if( colorIndex < 0 ) - return; - - if( colorIndex > ARRAYSIZE( gTracerColors )) - { - Con_Printf( S_ERROR "UserTracer with color > %d\n", ARRAYSIZE( gTracerColors )); - return; - } - - if(( p = R_AllocTracer( org, vel, life )) != NULL ) - { - p->context = deathcontext; - p->deathfunc = deathfunc; - p->color = colorIndex; - p->ramp = length; - } -} - -/* -=============== -R_TracerParticles - -allow more customization -=============== -*/ -particle_t *R_TracerParticles( float *org, float *vel, float life ) -{ - return R_AllocTracer( org, vel, life ); -} - -/* -=============== -R_SparkStreaks - -create a streak tracers -=============== -*/ -void R_SparkStreaks( const vec3_t pos, int count, int velocityMin, int velocityMax ) -{ - particle_t *p; - vec3_t vel; - int i; - - for( i = 0; icolor = 5; - p->type = pt_grav; - p->ramp = 0.5f; - } -} - -/* -=============== -R_Implosion - -make implosion tracers -=============== -*/ -void R_Implosion( const vec3_t end, float radius, int count, float life ) -{ - float dist = ( radius / 100.0f ); - vec3_t start, temp, vel; - float factor; - particle_t *p; - int i; - - if( life <= 0.0f ) life = 0.1f; // to avoid divide by zero - factor = -1.0 / life; - - for ( i = 0; i < count; i++ ) - { - temp[0] = dist * COM_RandomFloat( -100.0f, 100.0f ); - temp[1] = dist * COM_RandomFloat( -100.0f, 100.0f ); - temp[2] = dist * COM_RandomFloat( 0.0f, 100.0f ); - VectorScale( temp, factor, vel ); - VectorAdd( temp, end, start ); - - if(( p = R_AllocTracer( start, vel, life )) == NULL ) - return; - - p->type = pt_explode; - } -} - -/* -=============== -CL_ReadPointFile_f - -=============== -*/ -void CL_ReadPointFile_f( void ) -{ - char *afile, *pfile; - vec3_t org; - int count; - particle_t *p; - char filename[64]; - string token; - - Q_snprintf( filename, sizeof( filename ), "maps/%s.pts", clgame.mapname ); - afile = FS_LoadFile( filename, NULL, false ); - - if( !afile ) - { - Con_Printf( S_ERROR "couldn't open %s\n", filename ); - return; - } - - Con_Printf( "Reading %s...\n", filename ); - - count = 0; - pfile = afile; - - while( 1 ) - { - pfile = COM_ParseFile( pfile, token ); - if( !pfile ) break; - org[0] = Q_atof( token ); - - pfile = COM_ParseFile( pfile, token ); - if( !pfile ) break; - org[1] = Q_atof( token ); - - pfile = COM_ParseFile( pfile, token ); - if( !pfile ) break; - org[2] = Q_atof( token ); - - count++; - - if( !cl_free_particles ) - { - Con_Printf( S_ERROR "not enough free particles!\n" ); - break; - } - - // NOTE: can't use R_AllocParticle because this command - // may be executed from the console, while frametime is 0 - p = cl_free_particles; - cl_free_particles = p->next; - p->next = cl_active_particles; - cl_active_particles = p; - - p->ramp = 0; - p->type = pt_static; - p->die = cl.time + 99999; - p->color = (-count) & 15; - VectorCopy( org, p->org ); - VectorClear( p->vel ); - } - - Mem_Free( afile ); - - if( count ) Con_Printf( "%i points read\n", count ); - else Con_Printf( "map %s has no leaks!\n", clgame.mapname ); -} diff --git a/ref_gl/gl_rsurf.c b/ref_gl/gl_rsurf.c index 76c0e81e..1f42418c 100644 --- a/ref_gl/gl_rsurf.c +++ b/ref_gl/gl_rsurf.c @@ -13,8 +13,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" -#include "client.h" #include "gl_local.h" #include "mod_local.h" #include "mathlib.h" @@ -879,7 +877,7 @@ void DrawGLPolyChain( glpoly_t *p, float soffset, float toffset ) _inline qboolean R_HasLightmap( void ) { - if( CVAR_TO_BOOL( r_fullbright ) || !cl.worldmodel->lightdata ) + if( CVAR_TO_BOOL( r_fullbright ) || !WORLDMODEL->lightdata ) return false; if( RI.currententity ) @@ -1272,7 +1270,7 @@ void R_DrawTextureChains( void ) RI.currententity = clgame.entities; RI.currentmodel = RI.currententity->model; - if( FBitSet( world.flags, FWORLD_SKYSPHERE ) && !FBitSet( world.flags, FWORLD_CUSTOM_SKYBOX )) + if( FBitSet( WORLDMODEL->flags, FWORLD_SKYSPHERE ) && !FBitSet( WORLDMODEL->flags, FWORLD_CUSTOM_SKYBOX )) { pglDisable( GL_TEXTURE_2D ); pglColor3f( 1.0f, 1.0f, 1.0f ); @@ -1282,7 +1280,7 @@ void R_DrawTextureChains( void ) for( s = skychain; s != NULL; s = s->texturechain ) R_AddSkyBoxSurface( s ); - if( FBitSet( world.flags, FWORLD_SKYSPHERE ) && !FBitSet( world.flags, FWORLD_CUSTOM_SKYBOX )) + if( FBitSet( WORLDMODEL->flags, FWORLD_SKYSPHERE ) && !FBitSet( WORLDMODEL->flags, FWORLD_CUSTOM_SKYBOX )) { pglEnable( GL_TEXTURE_2D ); if( skychain ) @@ -1290,9 +1288,9 @@ void R_DrawTextureChains( void ) skychain = NULL; } - for( i = 0; i < cl.worldmodel->numtextures; i++ ) + for( i = 0; i < WORLDMODEL->numtextures; i++ ) { - t = cl.worldmodel->textures[i]; + t = WORLDMODEL->textures[i]; if( !t ) continue; s = t->texturechain; @@ -1300,7 +1298,7 @@ void R_DrawTextureChains( void ) if( !s || ( i == tr.skytexturenum )) continue; - if(( s->flags & SURF_DRAWTURB ) && clgame.movevars.wateralpha < 1.0f ) + if(( s->flags & SURF_DRAWTURB ) && MOVEVARS->wateralpha < 1.0f ) continue; // draw translucent water later if( Host_IsQuakeCompatible() && FBitSet( s->flags, SURF_TRANSPARENT )) @@ -1348,9 +1346,9 @@ void R_DrawAlphaTextureChains( void ) RI.currententity->curstate.rendermode = kRenderTransAlpha; draw_alpha_surfaces = false; - for( i = 0; i < cl.worldmodel->numtextures; i++ ) + for( i = 0; i < WORLDMODEL->numtextures; i++ ) { - t = cl.worldmodel->textures[i]; + t = WORLDMODEL->textures[i]; if( !t ) continue; s = t->texturechain; @@ -1384,7 +1382,7 @@ void R_DrawWaterSurfaces( void ) return; // non-transparent water is already drawed - if( clgame.movevars.wateralpha >= 1.0f ) + if( MOVEVARS->wateralpha >= 1.0f ) return; // restore worldmodel @@ -1399,11 +1397,11 @@ void R_DrawWaterSurfaces( void ) pglDisable( GL_ALPHA_TEST ); pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - pglColor4f( 1.0f, 1.0f, 1.0f, clgame.movevars.wateralpha ); + pglColor4f( 1.0f, 1.0f, 1.0f, MOVEVARS->wateralpha ); - for( i = 0; i < cl.worldmodel->numtextures; i++ ) + for( i = 0; i < WORLDMODEL->numtextures; i++ ) { - t = cl.worldmodel->textures[i]; + t = WORLDMODEL->textures[i]; if( !t ) continue; s = t->texturechain; @@ -1529,7 +1527,7 @@ void R_DrawBrushModel( cl_entity_t *e ) clmodel = e->model; // external models not loaded to VBO - if( clmodel->surfaces != cl.worldmodel->surfaces ) + if( clmodel->surfaces != WORLDMODEL->surfaces ) allow_vbo = false; if( !VectorIsNull( e->angles )) @@ -1610,22 +1608,22 @@ void R_DrawBrushModel( cl_entity_t *e ) continue; } - if( num_sorted < world.max_surfaces ) + if( num_sorted < WORLDMODEL->max_surfaces ) { - world.draw_surfaces[num_sorted].surf = psurf; - world.draw_surfaces[num_sorted].cull = cull_type; + WORLDMODEL->draw_surfaces[num_sorted].surf = psurf; + WORLDMODEL->draw_surfaces[num_sorted].cull = cull_type; num_sorted++; } } // sort faces if needs if( !FBitSet( clmodel->flags, MODEL_LIQUID ) && e->curstate.rendermode == kRenderTransTexture && !CVAR_TO_BOOL( gl_nosort )) - qsort( world.draw_surfaces, num_sorted, sizeof( sortedface_t ), R_SurfaceCompare ); + qsort( WORLDMODEL->draw_surfaces, num_sorted, sizeof( sortedface_t ), R_SurfaceCompare ); // draw sorted translucent surfaces for( i = 0; i < num_sorted; i++ ) - if( !allow_vbo || !R_AddSurfToVBO( world.draw_surfaces[i].surf, true ) ) - R_RenderBrushPoly( world.draw_surfaces[i].surf, world.draw_surfaces[i].cull ); + if( !allow_vbo || !R_AddSurfToVBO( WORLDMODEL->draw_surfaces[i].surf, true ) ) + R_RenderBrushPoly( WORLDMODEL->draw_surfaces[i].surf, WORLDMODEL->draw_surfaces[i].cull ); R_DrawVBO( R_HasLightmap(), true ); if( e->curstate.rendermode == kRenderTransColor ) @@ -1775,7 +1773,7 @@ Allocate memory for arrays, fill it with vertex attribs and upload to GPU */ void R_GenerateVBO() { - int numtextures = cl.worldmodel->numtextures; + int numtextures = WORLDMODEL->numtextures; int numlightmaps = gl_lms.current_lightmap_texture; int k, len = 0; vboarray_t *vbo; @@ -1806,7 +1804,7 @@ void R_GenerateVBO() vbos.maxtexture = 0; vbos.textures = Mem_Calloc( vbos.mempool, numtextures * numlightmaps * sizeof( vbotexture_t ) ); - vbos.surfdata = Mem_Calloc( vbos.mempool, cl.worldmodel->numsurfaces * sizeof( vbosurfdata_t ) ); + vbos.surfdata = Mem_Calloc( vbos.mempool, WORLDMODEL->numsurfaces * sizeof( vbosurfdata_t ) ); vbos.arraylist = vbo = Mem_Calloc( vbos.mempool, sizeof( vboarray_t ) ); vbos.decaldata = Mem_Calloc( vbos.mempool, sizeof( vbodecaldata_t ) ); vbos.decaldata->lm = Mem_Calloc( vbos.mempool, sizeof( msurface_t* ) * numlightmaps ); @@ -1821,9 +1819,9 @@ void R_GenerateVBO() int i; vbotexture_t *vbotex = &vbos.textures[k * numtextures + j]; - for( i = 0; i < cl.worldmodel->numsurfaces; i++ ) + for( i = 0; i < WORLDMODEL->numsurfaces; i++ ) { - msurface_t *surf = &cl.worldmodel->surfaces[i]; + msurface_t *surf = &WORLDMODEL->surfaces[i]; if( surf->flags & ( SURF_DRAWSKY | SURF_DRAWTURB | SURF_CONVEYOR | SURF_DRAWTURB_QUADS ) ) continue; @@ -1831,7 +1829,7 @@ void R_GenerateVBO() if( surf->lightmaptexturenum != k ) continue; - if( R_TextureAnimation( surf ) != cl.worldmodel->textures[j] ) + if( R_TextureAnimation( surf ) != WORLDMODEL->textures[j] ) continue; if( vbo->array_len + surf->polys->numverts > USHRT_MAX ) @@ -1888,9 +1886,9 @@ void R_GenerateVBO() if( maxindex < vbotex->len ) maxindex = vbotex->len; - for( i = 0; i < cl.worldmodel->numsurfaces; i++ ) + for( i = 0; i < WORLDMODEL->numsurfaces; i++ ) { - msurface_t *surf = &cl.worldmodel->surfaces[i]; + msurface_t *surf = &WORLDMODEL->surfaces[i]; int l; if( surf->flags & ( SURF_DRAWSKY | SURF_DRAWTURB | SURF_CONVEYOR | SURF_DRAWTURB_QUADS ) ) @@ -1899,7 +1897,7 @@ void R_GenerateVBO() if( surf->lightmaptexturenum != k ) continue; - if( R_TextureAnimation( surf ) != cl.worldmodel->textures[j] ) + if( R_TextureAnimation( surf ) != WORLDMODEL->textures[j] ) continue; // switch to next array @@ -1935,9 +1933,9 @@ void R_GenerateVBO() vbo->array[len + l].lm_tc[0] = v[5]; vbo->array[len + l].lm_tc[1] = v[6]; #ifdef NO_TEXTURE_MATRIX - if( cl.worldmodel->textures[j]->dt_texturenum ) + if( WORLDMODEL->textures[j]->dt_texturenum ) { - gl_texture_t *glt = R_GetTexture( cl.worldmodel->textures[j]->gl_texturenum ); + gl_texture_t *glt = R_GetTexture( WORLDMODEL->textures[j]->gl_texturenum ); vbo->array[len + l].dt_tc[0] = v[3] * glt->xscale; vbo->array[len + l].dt_tc[1] = v[4] * glt->yscale; } @@ -2162,7 +2160,7 @@ static texture_t *R_SetupVBOTexture( texture_t *tex, int number ) return tex; if( !tex ) - tex = R_TextureAnim( cl.worldmodel->textures[number] ); + tex = R_TextureAnim( WORLDMODEL->textures[number] ); if( CVAR_TO_BOOL( r_detailtextures ) && tex->dt_texturenum && mtst.tmu_dt != -1 ) { @@ -2307,7 +2305,7 @@ static void R_DrawLightmappedVBO( vboarray_t *vbo, vbotexture_t *vbotex, texture { int smax, tmax; byte *base; - uint indexbase = vbos.surfdata[((char*)surf - (char*)cl.worldmodel->surfaces) / sizeof( *surf )].startindex; + uint indexbase = vbos.surfdata[((char*)surf - (char*)WORLDMODEL->surfaces) / sizeof( *surf )].startindex; uint index; mextrasurf_t *info; // this stores current dlight offset decal_t *pdecal; @@ -2623,7 +2621,7 @@ Draw generated index arrays */ void R_DrawVBO( qboolean drawlightmap, qboolean drawtextures ) { - int numtextures = cl.worldmodel->numtextures; + int numtextures = WORLDMODEL->numtextures; int numlightmaps = gl_lms.current_lightmap_texture; int k; vboarray_t *vbo = vbos.arraylist; @@ -2955,10 +2953,10 @@ static qboolean R_CheckLightMap( msurface_t *fa ) qboolean R_AddSurfToVBO( msurface_t *surf, qboolean buildlightmap ) { - if( CVAR_TO_BOOL(r_vbo) && vbos.surfdata[surf - cl.worldmodel->surfaces].vbotexture ) + if( CVAR_TO_BOOL(r_vbo) && vbos.surfdata[surf - WORLDMODEL->surfaces].vbotexture ) { // find vbotexture_t assotiated with this surface - int idx = surf - cl.worldmodel->surfaces; + int idx = surf - WORLDMODEL->surfaces; vbotexture_t *vbotex = vbos.surfdata[idx].vbotexture; int texturenum = vbos.surfdata[idx].texturenum; @@ -2974,7 +2972,7 @@ qboolean R_AddSurfToVBO( msurface_t *surf, qboolean buildlightmap ) if( vbos.mintexture > texturenum ) vbos.mintexture = texturenum; - buildlightmap &= !CVAR_TO_BOOL( r_fullbright ) && !!cl.worldmodel->lightdata; + buildlightmap &= !CVAR_TO_BOOL( r_fullbright ) && !!WORLDMODEL->lightdata; if( buildlightmap && R_CheckLightMap( surf ) ) { @@ -3083,7 +3081,7 @@ loc0: R_RecursiveWorldNode( node->children[side], clipflags ); // draw stuff - for( c = node->numsurfaces, surf = cl.worldmodel->surfaces + node->firstsurface; c; c--, surf++ ) + for( c = node->numsurfaces, surf = WORLDMODEL->surfaces + node->firstsurface; c; c--, surf++ ) { if( R_CullSurface( surf, &RI.frustum, clipflags )) continue; @@ -3211,7 +3209,7 @@ void R_DrawWorldTopView( mnode_t *node, uint clipflags ) } // draw stuff - for( c = node->numsurfaces, surf = cl.worldmodel->surfaces + node->firstsurface; c; c--, surf++ ) + for( c = node->numsurfaces, surf = WORLDMODEL->surfaces + node->firstsurface; c; c--, surf++ ) { // don't process the same surface twice if( surf->visframe == tr.framecount ) @@ -3324,14 +3322,14 @@ void R_DrawWorld( void ) start = Sys_DoubleTime(); if( RI.drawOrtho ) - R_DrawWorldTopView( cl.worldmodel->nodes, RI.frustum.clipFlags ); - else R_RecursiveWorldNode( cl.worldmodel->nodes, RI.frustum.clipFlags ); + R_DrawWorldTopView( WORLDMODEL->nodes, RI.frustum.clipFlags ); + else R_RecursiveWorldNode( WORLDMODEL->nodes, RI.frustum.clipFlags ); end = Sys_DoubleTime(); r_stats.t_world_node = end - start; start = Sys_DoubleTime(); - R_DrawVBO( !CVAR_TO_BOOL(r_fullbright) && !!cl.worldmodel->lightdata, true ); + R_DrawVBO( !CVAR_TO_BOOL(r_fullbright) && !!WORLDMODEL->lightdata, true ); R_DrawTextureChains(); @@ -3392,12 +3390,12 @@ void R_MarkLeaves( void ) if( RI.viewleaf->contents == CONTENTS_EMPTY ) { VectorSet( test, RI.pvsorigin[0], RI.pvsorigin[1], RI.pvsorigin[2] - 16.0f ); - leaf = Mod_PointInLeaf( test, cl.worldmodel->nodes ); + leaf = Mod_PointInLeaf( test, WORLDMODEL->nodes ); } else { VectorSet( test, RI.pvsorigin[0], RI.pvsorigin[1], RI.pvsorigin[2] + 16.0f ); - leaf = Mod_PointInLeaf( test, cl.worldmodel->nodes ); + leaf = Mod_PointInLeaf( test, WORLDMODEL->nodes ); } if(( leaf->contents != CONTENTS_SOLID ) && ( RI.viewleaf != leaf )) @@ -3414,17 +3412,17 @@ void R_MarkLeaves( void ) RI.oldviewleaf = RI.viewleaf; tr.visframecount++; - if( r_novis->value || RI.drawOrtho || !RI.viewleaf || !cl.worldmodel->visdata ) + if( r_novis->value || RI.drawOrtho || !RI.viewleaf || !WORLDMODEL->visdata ) novis = true; - Mod_FatPVS( RI.pvsorigin, REFPVS_RADIUS, RI.visbytes, world.visbytes, FBitSet( RI.params, RP_OLDVIEWLEAF ), novis ); - if( force && !novis ) Mod_FatPVS( test, REFPVS_RADIUS, RI.visbytes, world.visbytes, true, novis ); + Mod_FatPVS( RI.pvsorigin, REFPVS_RADIUS, RI.visbytes, WORLDMODEL->visbytes, FBitSet( RI.params, RP_OLDVIEWLEAF ), novis ); + if( force && !novis ) Mod_FatPVS( test, REFPVS_RADIUS, RI.visbytes, WORLDMODEL->visbytes, true, novis ); - for( i = 0; i < cl.worldmodel->numleafs; i++ ) + for( i = 0; i < WORLDMODEL->numleafs; i++ ) { if( CHECKVISBIT( RI.visbytes, i )) { - node = (mnode_t *)&cl.worldmodel->leafs[i+1]; + node = (mnode_t *)&WORLDMODEL->leafs[i+1]; do { if( node->visframe == tr.visframecount ) diff --git a/ref_gl/gl_sprite.c b/ref_gl/gl_sprite.c index b98a3a2c..7a3431dc 100644 --- a/ref_gl/gl_sprite.c +++ b/ref_gl/gl_sprite.c @@ -13,8 +13,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" -#include "client.h" #include "gl_local.h" #include "pm_local.h" #include "sprite.h" diff --git a/ref_gl/gl_studio.c b/ref_gl/gl_studio.c index 0648ae29..c0bc6c25 100644 --- a/ref_gl/gl_studio.c +++ b/ref_gl/gl_studio.c @@ -13,20 +13,25 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" -#include "client.h" +#include "gl_local.h" #include "mathlib.h" #include "const.h" #include "r_studioint.h" #include "triangleapi.h" #include "studio.h" #include "pm_local.h" -#include "gl_local.h" #include "cl_tent.h" #define EVENT_CLIENT 5000 // less than this value it's a server-side studio events #define MAX_LOCALLIGHTS 4 +typedef struct +{ + char name[MAX_OSPATH]; + char modelname[MAX_OSPATH]; + model_t *model; +} player_model_t; + CVAR_DEFINE_AUTO( r_glowshellfreq, "2.2", 0, "glowing shell frequency update" ); CVAR_DEFINE_AUTO( r_shadows, "0", 0, "cast shadows from models" ); @@ -3670,6 +3675,12 @@ void CL_InitStudioAPI( void ) { pStudioDraw = &gStudioDraw; + // trying to grab them from client.dll + cl_righthand = Cvar_FindVar( "cl_righthand" ); + + if( cl_righthand == NULL ) + cl_righthand = Cvar_Get( "cl_righthand", "0", FCVAR_ARCHIVE, "flip viewmodel (left to right)" ); + // Xash will be used internal StudioModelRenderer if( !clgame.dllFuncs.pfnGetStudioModelInterface ) return; diff --git a/ref_gl/gl_warp.c b/ref_gl/gl_warp.c index 4acc7fe6..c0b8542e 100644 --- a/ref_gl/gl_warp.c +++ b/ref_gl/gl_warp.c @@ -13,8 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" -#include "client.h" + #include "gl_local.h" #include "wadfile.h" @@ -311,7 +310,7 @@ void R_AddSkyBoxSurface( msurface_t *fa ) float *v; int i; - if( FBitSet( world.flags, FWORLD_SKYSPHERE ) && fa->polys && !FBitSet( world.flags, FWORLD_CUSTOM_SKYBOX )) + if( FBitSet( WORLDMODEL->flags, FWORLD_SKYSPHERE ) && fa->polys && !FBitSet( WORLDMODEL->flags, FWORLD_CUSTOM_SKYBOX )) { glpoly_t *p = fa->polys; @@ -355,7 +354,7 @@ void R_UnloadSkybox( void ) tr.skyboxbasenum = 5800; // set skybox base (to let some mods load hi-res skyboxes) memset( tr.skyboxTextures, 0, sizeof( tr.skyboxTextures )); - ClearBits( world.flags, FWORLD_CUSTOM_SKYBOX ); + ClearBits( WORLDMODEL->flags, FWORLD_CUSTOM_SKYBOX ); } /* @@ -455,7 +454,7 @@ void R_SetupSky( const char *skyboxname ) if( i == 6 ) { - SetBits( world.flags, FWORLD_CUSTOM_SKYBOX ); + SetBits( WORLDMODEL->flags, FWORLD_CUSTOM_SKYBOX ); Con_DPrintf( "done\n" ); return; // loaded } diff --git a/ref_gl/wscript b/ref_gl/wscript index 102581cc..f06c5b90 100644 --- a/ref_gl/wscript +++ b/ref_gl/wscript @@ -33,7 +33,8 @@ def build(bld): source = bld.path.ant_glob(['*.c']) includes = ['.', - '../engine/common', + '../engine', + '../engine/common', '../engine/server', '../engine/client', '../common', diff --git a/wscript b/wscript index 80534708..f4f4f8fd 100644 --- a/wscript +++ b/wscript @@ -13,7 +13,7 @@ import fwgslib VERSION = '0.99' APPNAME = 'xash3d-fwgs' -SUBDIRS = [ 'engine', 'game_launch', 'mainui', 'vgui_support' ] +SUBDIRS = [ 'engine', 'game_launch', 'vgui_support', 'ref_gl' ] top = '.' def options(opt):