diff --git a/common/backends.h b/common/backends.h index bd0d7769..f95a551f 100644 --- a/common/backends.h +++ b/common/backends.h @@ -18,6 +18,7 @@ GNU General Public License for more details. #define BACKENDS_H // video backends (XASH_VIDEO) +#define VIDEO_DONTCARE -1 // a special mode for ref_dll #define VIDEO_NULL 0 #define VIDEO_SDL 1 #define VIDEO_ANDROID 2 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/defaults.h b/common/defaults.h index 7eb68476..da4d07b2 100644 --- a/common/defaults.h +++ b/common/defaults.h @@ -95,7 +95,11 @@ SETUP BACKENDS DEFINITIONS // fallback to NULL // #ifndef XASH_VIDEO - #define XASH_VIDEO VIDEO_NULL + #ifdef REF_DLL + #define XASH_VIDEO VIDEO_DONTCARE + #else + #define XASH_VIDEO VIDEO_NULL + #endif #endif #ifndef XASH_SOUND @@ -150,6 +154,10 @@ Default build-depended cvar and constant values #define DEFAULT_FULLSCREEN 1 #endif +#ifndef DEFAULT_RENDERER + #define DEFAULT_RENDERER "ref_gl" +#endif + #if TARGET_OS_IPHONE #define DEFAULT_CON_MAXFRAC "0.5" #else diff --git a/common/port.h b/common/port.h index 79ef55eb..62240040 100644 --- a/common/port.h +++ b/common/port.h @@ -54,6 +54,8 @@ GNU General Public License for more details. #define OPEN_COMMAND "xdg-open" #endif + #define OS_LIB_PREFIX "lib" + #if defined(__ANDROID__) #if defined(LOAD_HARDFP) #define POSTFIX "_hardfp" @@ -78,6 +80,7 @@ GNU General Public License for more details. #define __stdcall #define _inline static inline + #define FORCEINLINE inline __attribute__((always_inline)) #define O_BINARY 0 // O_BINARY is Windows extension #define O_TEXT 0 // O_TEXT is Windows extension @@ -113,6 +116,9 @@ GNU General Public License for more details. #else // WIN32 #ifdef __MINGW32__ #define _inline static inline + #define FORCEINLINE inline __attribute__((always_inline)) + #else + #define FORCEINLINE __forceinline #endif #define strcasecmp _stricmp @@ -156,4 +162,8 @@ GNU General Public License for more details. #define USHRT_MAX 65535 #endif +#ifdef XASH_SDL +#include +#endif + #endif // PORT_H diff --git a/common/r_efx.h b/common/r_efx.h index 9ee1f9e8..8cffd850 100644 --- a/common/r_efx.h +++ b/common/r_efx.h @@ -85,6 +85,7 @@ color24 gTracerColors[] = #define FTENT_SCALE 0x00100000 // An experiment typedef struct tempent_s TEMPENTITY; +struct pmtrace_s; typedef struct tempent_s { int flags; diff --git a/common/render_api.h b/common/render_api.h index f8c9ecf5..a7276e21 100644 --- a/common/render_api.h +++ b/common/render_api.h @@ -235,7 +235,8 @@ typedef struct render_api_s float (*pfnTime)( void ); // Sys_DoubleTime void (*Cvar_Set)( const char *name, const char *value ); void (*S_FadeMusicVolume)( float fadePercent ); // fade background track (0-100 percents) - void (*SetRandomSeed)( long lSeed ); // set custom seed for RANDOM_FLOAT\RANDOM_LONG for predictable random + // a1ba: changed long to int + void (*SetRandomSeed)( int lSeed ); // set custom seed for RANDOM_FLOAT\RANDOM_LONG for predictable random // ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 37 } render_api_t; @@ -254,7 +255,7 @@ typedef struct render_interface_s // clear decals by engine request (e.g. for demo recording or vid_restart) void (*R_ClearStudioDecals)( void ); // grab r_speeds message - qboolean (*R_SpeedsMessage)( char *out, size_t size ); + qboolean (*R_SpeedsMessage)( char *out, size_t size ); // alloc or destroy model custom data void (*Mod_ProcessUserData)( struct model_s *mod, qboolean create, const byte *buffer ); // alloc or destroy entity custom data diff --git a/common/xash3d_types.h b/common/xash3d_types.h index 18966222..214c97c7 100644 --- a/common/xash3d_types.h +++ b/common/xash3d_types.h @@ -1,6 +1,13 @@ // basic typedefs #ifndef XASH_TYPES_H #define XASH_TYPES_H + +#ifdef _WIN32 +#include // off_t +#endif // _WIN32 + +#include // off_t + typedef unsigned char byte; typedef int sound_t; typedef float vec_t; @@ -30,4 +37,114 @@ 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(__GNUC__) +#ifdef __i386__ +#define EXPORT __attribute__ ((visibility ("default"),force_align_arg_pointer)) +#define GAME_EXPORT __attribute((force_align_arg_pointer)) +#else +#define EXPORT __attribute__ ((visibility ("default"))) +#define GAME_EXPORT +#endif +#elif defined(_MSC_VER) +#define EXPORT __declspec( dllexport ) +#define GAME_EXPORT +#else +#define EXPORT +#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; + +typedef void (*setpair_t)( const char *key, const char *value, void *buffer, void *numpairs ); + +// config strings are a general means of communication from +// the server to all connected clients. +// each config string can be at most CS_SIZE characters. +#define MAX_QPATH 64 // max length of a game pathname +#define MAX_OSPATH 260 // max length of a filesystem pathname +#define CS_SIZE 64 // size of one config string +#define CS_TIME 16 // size of time string + #endif // XASH_TYPES_H diff --git a/engine/client/avi/avi_win.c b/engine/client/avi/avi_win.c index 616e2ca2..19651c14 100644 --- a/engine/client/avi/avi_win.c +++ b/engine/client/avi/avi_win.c @@ -16,7 +16,6 @@ GNU General Public License for more details. #ifdef _WIN32 #include "common.h" #include "client.h" -#include "gl_local.h" #include // video for windows // msvfw32.dll exports diff --git a/engine/client/cl_cmds.c b/engine/client/cl_cmds.c index a5d711d6..fca37845 100644 --- a/engine/client/cl_cmds.c +++ b/engine/client/cl_cmds.c @@ -15,7 +15,6 @@ GNU General Public License for more details. #include "common.h" #include "client.h" -#include "gl_local.h" /* ==================== @@ -344,7 +343,7 @@ void CL_LevelShot_f( void ) // check for exist if( cls.demoplayback && ( cls.demonum != -1 )) { - Q_sprintf( cls.shotname, "levelshots/%s_%s.bmp", cls.demoname, glState.wideScreen ? "16x9" : "4x3" ); + Q_sprintf( cls.shotname, "levelshots/%s_%s.bmp", cls.demoname, refState.wideScreen ? "16x9" : "4x3" ); Q_snprintf( filename, sizeof( filename ), "%s.dem", cls.demoname ); // make sure what levelshot is newer than demo @@ -353,7 +352,7 @@ void CL_LevelShot_f( void ) } else { - Q_sprintf( cls.shotname, "levelshots/%s_%s.bmp", clgame.mapname, glState.wideScreen ? "16x9" : "4x3" ); + Q_sprintf( cls.shotname, "levelshots/%s_%s.bmp", clgame.mapname, refState.wideScreen ? "16x9" : "4x3" ); // make sure what levelshot is newer than bsp ft1 = FS_FileTime( cl.worldmodel->name, false ); @@ -424,53 +423,7 @@ void CL_SetSky_f( void ) return; } - R_SetupSky( Cmd_Argv( 1 )); -} - -/* -================ -SCR_TimeRefresh_f - -timerefresh [noflip] -================ -*/ -void SCR_TimeRefresh_f( void ) -{ - int i; - double start, stop; - double time; - - if( cls.state != ca_active ) - return; - - start = Sys_DoubleTime(); - - // run without page flipping like GoldSrc - if( Cmd_Argc() == 1 ) - { - pglDrawBuffer( GL_FRONT ); - for( i = 0; i < 128; i++ ) - { - RI.viewangles[1] = i / 128.0 * 360.0f; - R_RenderScene(); - } - pglFinish(); - R_EndFrame(); - } - else - { - for( i = 0; i < 128; i++ ) - { - R_BeginFrame( true ); - RI.viewangles[1] = i / 128.0 * 360.0f; - R_RenderScene(); - R_EndFrame(); - } - } - - stop = Sys_DoubleTime (); - time = (stop - start); - Con_Printf( "%f seconds (%f fps)\n", time, 128 / time ); + ref.dllFuncs.R_SetupSky( Cmd_Argv( 1 )); } /* @@ -482,6 +435,6 @@ viewpos (level-designer helper) */ void SCR_Viewpos_f( void ) { - Con_Printf( "org ( %g %g %g )\n", RI.vieworg[0], RI.vieworg[1], RI.vieworg[2] ); - Con_Printf( "ang ( %g %g %g )\n", RI.viewangles[0], RI.viewangles[1], RI.viewangles[2] ); -} \ No newline at end of file + Con_Printf( "org ( %g %g %g )\n", refState.vieworg[0], refState.vieworg[1], refState.vieworg[2] ); + Con_Printf( "ang ( %g %g %g )\n", refState.viewangles[0], refState.viewangles[1], refState.viewangles[2] ); +} diff --git a/engine/client/cl_debug.c b/engine/client/cl_debug.c index 4704b800..e483cb23 100644 --- a/engine/client/cl_debug.c +++ b/engine/client/cl_debug.c @@ -17,7 +17,6 @@ GNU General Public License for more details. #include "client.h" #include "net_encode.h" #include "particledef.h" -#include "gl_local.h" #include "cl_tent.h" #include "shake.h" #include "hltv.h" @@ -239,4 +238,4 @@ void CL_WriteMessageHistory( void ) if( host_developer.value >= DEV_EXTENDED ) CL_WriteErrorMessage( MSG_GetNumBytesRead( msg ) - 1, msg ); cls_message_debug.parsing = false; -} \ No newline at end of file +} diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index f3e9e69a..0106780d 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -15,7 +15,6 @@ GNU General Public License for more details. #include "common.h" #include "client.h" -#include "gl_local.h" #include "net_encode.h" #define dem_unknown 0 // unknown command @@ -500,7 +499,7 @@ void CL_DrawDemoRecording( void ) Q_memprint( pos ), (int)(cls.demotime / 60.0f ), (int)fmod( cls.demotime, 60.0f )); Con_DrawStringLen( string, &len, NULL ); - Con_DrawString(( glState.width - len ) >> 1, glState.height >> 4, string, color ); + Con_DrawString(( refState.width - len ) >> 1, refState.height >> 4, string, color ); } /* diff --git a/engine/client/gl_refrag.c b/engine/client/cl_efrag.c similarity index 97% rename from engine/client/gl_refrag.c rename to engine/client/cl_efrag.c index da73f149..d8ce446c 100644 --- a/engine/client/gl_refrag.c +++ b/engine/client/cl_efrag.c @@ -14,11 +14,11 @@ 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" #include "studio.h" +#include "world.h" // BOX_ON_PLANE_SIDE +#include "client.h" +#include "mathlib.h" /* =============================================================================== @@ -103,7 +103,7 @@ static void R_SplitEntityOnNode( mnode_t *node ) return; // no free fragments... } - clgame.free_efrags = clgame.free_efrags->entnext; + clgame.free_efrags = ef->entnext; ef->entity = r_addent; // add the entity link @@ -206,4 +206,4 @@ void R_StoreEfrags( efrag_t **ppefrag, int framecount ) break; } } -} \ No newline at end of file +} diff --git a/engine/client/gl_rpart.c b/engine/client/cl_efx.c similarity index 54% rename from engine/client/gl_rpart.c rename to engine/client/cl_efx.c index e6e070e0..4d0c4c4e 100644 --- a/engine/client/gl_rpart.c +++ b/engine/client/cl_efx.c @@ -1,29 +1,11 @@ -/* -cl_part.c - particles and tracers -Copyright (C) 2010 Uncle Mike -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -*/ #include "common.h" #include "client.h" -#include "gl_local.h" +#include "customentity.h" #include "r_efx.h" -#include "event_flags.h" -#include "entity_types.h" -#include "triangleapi.h" -#include "pm_local.h" #include "cl_tent.h" -#include "studio.h" - +#include "pm_local.h" #define PART_SIZE Q_max( 0.5f, cl_draw_particles->value ) /* @@ -37,29 +19,8 @@ PARTICLES MANAGEMENT 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; @@ -139,10 +100,6 @@ void CL_InitParticles( void ) 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" ); @@ -203,6 +160,26 @@ void CL_FreeParticle( particle_t *p ) cl_free_particles = p; } +/* +================ +CL_AllocParticleFast + +unconditionally give new particle pointer from cl_free_particles +================ +*/ +particle_t *CL_AllocParticleFast( void ) +{ + particle_t *p = NULL; + + if( cl_free_particles ) + { + p = cl_free_particles; + cl_free_particles = p->next; + } + + return p; +} + /* ================ R_AllocParticle @@ -218,7 +195,7 @@ particle_t *R_AllocParticle( void (*callback)( particle_t*, float )) return NULL; // never alloc particles when we not in game - if( tr.frametime == 0.0 ) return NULL; +// if( tr.frametime == 0.0 ) return NULL; if( !cl_free_particles ) { @@ -269,7 +246,7 @@ particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life ) return NULL; // never alloc particles when we not in game - if( tr.frametime == 0.0 ) return NULL; + //if( tr.frametime == 0.0 ) return NULL; if( !cl_free_particles ) { @@ -298,402 +275,777 @@ particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life ) return p; } +/* +============================================================== + +VIEWBEAMS MANAGEMENT + +============================================================== +*/ +BEAM *cl_active_beams; +BEAM *cl_free_beams; +BEAM *cl_viewbeams = NULL; // beams pool + + +/* +============================================================== + +BEAM ALLOCATE & PROCESSING + +============================================================== +*/ + /* ============== -R_FreeDeadParticles +R_BeamSetAttributes -Free particles that time has expired +set beam attributes ============== */ -void R_FreeDeadParticles( particle_t **ppparticles ) +static void R_BeamSetAttributes( BEAM *pbeam, float r, float g, float b, float framerate, int startFrame ) { - particle_t *p, *kill; + pbeam->frame = (float)startFrame; + pbeam->frameRate = framerate; + pbeam->r = r; + pbeam->g = g; + pbeam->b = b; +} - // 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; - } - } + +/* +============== +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_DrawParticles +CL_ClearViewBeams -update particle color, position, free expired and draw it ================ */ -void CL_DrawParticles( double frametime ) +void CL_ClearViewBeams( void ) { - 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; - vec3_t right, up; - color24 *pColor; - int alpha; - float size; - - if( !cl_draw_particles->value ) - return; - - R_FreeDeadParticles( &cl_active_particles ); - - if( !cl_active_particles ) - return; // nothing to draw? - - pglEnable( GL_BLEND ); - pglDisable( GL_ALPHA_TEST ); - pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - - GL_Bind( XASH_TEXTURE0, tr.particleTexture ); - pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - pglDepthMask( GL_FALSE ); - - pglBegin( GL_QUADS ); - - for( p = cl_active_particles; p; p = p->next ) - { - if(( p->type != pt_blob ) || ( p->packedColor == 255 )) - { - size = PART_SIZE; // get initial size of particle - - // scale up to keep particles from disappearing - size += (p->org[0] - RI.vieworg[0]) * RI.cull_vforward[0]; - size += (p->org[1] - RI.vieworg[1]) * RI.cull_vforward[1]; - size += (p->org[2] - RI.vieworg[2]) * RI.cull_vforward[2]; - - if( size < 20.0f ) size = PART_SIZE; - else size = PART_SIZE + size * 0.002f; - - // scale the axes by radius - VectorScale( RI.cull_vright, size, right ); - VectorScale( RI.cull_vup, size, up ); - - p->color = bound( 0, p->color, 255 ); - pColor = &clgame.palette[p->color]; - - alpha = 255 * (p->die - cl.time) * 16.0f; - if( alpha > 255 || p->type == pt_static ) - alpha = 255; - - pglColor4ub( LightToTexGamma( pColor->r ), LightToTexGamma( pColor->g ), LightToTexGamma( pColor->b ), alpha ); - - pglTexCoord2f( 0.0f, 1.0f ); - pglVertex3f( p->org[0] - right[0] + up[0], p->org[1] - right[1] + up[1], p->org[2] - right[2] + up[2] ); - pglTexCoord2f( 0.0f, 0.0f ); - pglVertex3f( p->org[0] + right[0] + up[0], p->org[1] + right[1] + up[1], p->org[2] + right[2] + up[2] ); - pglTexCoord2f( 1.0f, 0.0f ); - pglVertex3f( p->org[0] + right[0] - up[0], p->org[1] + right[1] - up[1], p->org[2] + right[2] - up[2] ); - pglTexCoord2f( 1.0f, 1.0f ); - pglVertex3f( p->org[0] - right[0] - up[0], p->org[1] - right[1] - up[1], p->org[2] - right[2] - up[2] ); - r_stats.c_particle_count++; - } - - if( p->type != pt_clientcustom ) - { - // update position. - VectorMA( p->org, frametime, p->vel, p->org ); - } - - switch( p->type ) - { - case pt_static: - break; - case pt_fire: - p->ramp += time1; - if( p->ramp >= 6.0f ) p->die = -1.0f; - else p->color = ramp3[(int)p->ramp]; - p->vel[2] += grav; - break; - case pt_explode: - p->ramp += time2; - if( p->ramp >= 8.0f ) p->die = -1.0f; - else p->color = ramp1[(int)p->ramp]; - VectorMA( p->vel, dvel, p->vel, p->vel ); - p->vel[2] -= grav; - break; - case pt_explode2: - p->ramp += time3; - if( p->ramp >= 8.0f ) p->die = -1.0f; - else p->color = ramp2[(int)p->ramp]; - VectorMA( p->vel,-frametime, p->vel, p->vel ); - p->vel[2] -= grav; - break; - case pt_blob: - if( p->packedColor == 255 ) - { - // normal blob explosion - VectorMA( p->vel, dvel, p->vel, p->vel ); - p->vel[2] -= grav; - break; - } - case pt_blob2: - if( p->packedColor == 255 ) - { - // normal blob explosion - p->vel[0] -= p->vel[0] * dvel; - p->vel[1] -= p->vel[1] * dvel; - p->vel[2] -= grav; - } - else - { - p->ramp += time2; - if( p->ramp >= 9.0f ) p->ramp = 0.0f; - p->color = gSparkRamp[(int)p->ramp]; - VectorMA( p->vel, -frametime * 0.5f, p->vel, p->vel ); - p->type = COM_RandomLong( 0, 3 ) ? pt_blob : pt_blob2; - p->vel[2] -= grav * 5.0f; - } - break; - case pt_grav: - p->vel[2] -= grav * 20.0f; - break; - case pt_slowgrav: - p->vel[2] -= grav; - break; - case pt_vox_grav: - p->vel[2] -= grav * 8.0f; - break; - case pt_vox_slowgrav: - p->vel[2] -= grav * 4.0f; - break; - case pt_clientcustom: - if( p->callback ) - p->callback( p, frametime ); - break; - } - } - - pglEnd(); - pglDepthMask( GL_TRUE ); -} - -/* -================ -CL_CullTracer - -check tracer bbox -================ -*/ -static qboolean CL_CullTracer( particle_t *p, const vec3_t start, const vec3_t end ) -{ - vec3_t mins, maxs; int i; - // compute the bounding box - for( i = 0; i < 3; 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 +============== +*/ +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 ) { - if( start[i] < end[i] ) + cl_entity_t *beament; + pnext = pbeam->next; + + // link into new list. + if( R_BeamGetEntity( pbeam->startEntity ) != pDeadEntity ) { - mins[i] = start[i]; - maxs[i] = end[i]; + 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 { - mins[i] = end[i]; - maxs[i] = start[i]; - } - - // don't let it be zero sized - if( mins[i] == maxs[i] ) - { - maxs[i] += gTracerSize[p->type] * 2.0f; + // stay active + pbeam->next = pnewlist; + pnewlist = pbeam; } + + pbeam = pnext; } - // check bbox - return R_CullBox( mins, maxs ); + // We now have a new list with the bogus stuff released. + cl_active_beams = pnewlist; } -/* -================ -CL_DrawTracers - -update tracer color, position, free expired and draw it -================ -*/ -void CL_DrawTracers( double frametime ) -{ - float scale, atten, gravity; - vec3_t screenLast, screen; - vec3_t start, end, delta; - particle_t *p; - - if( !cl_draw_tracers->value ) - return; - - // update tracer color if this is changed - if( FBitSet( tracerred->flags|tracergreen->flags|tracerblue->flags|traceralpha->flags, FCVAR_CHANGED )) - { - gTracerColors[4].r = (byte)(tracerred->value * traceralpha->value * 255); - gTracerColors[4].g = (byte)(tracergreen->value * traceralpha->value * 255); - gTracerColors[4].b = (byte)(tracerblue->value * traceralpha->value * 255); - ClearBits( tracerred->flags, FCVAR_CHANGED ); - ClearBits( tracergreen->flags, FCVAR_CHANGED ); - ClearBits( tracerblue->flags, FCVAR_CHANGED ); - ClearBits( traceralpha->flags, FCVAR_CHANGED ); - } - - R_FreeDeadParticles( &cl_active_tracers ); - - if( !cl_active_tracers ) - return; // nothing to draw? - - if( !TriSpriteTexture( cl_sprite_dot, 0 )) - return; - - pglEnable( GL_BLEND ); - pglBlendFunc( GL_SRC_ALPHA, GL_ONE ); - pglDisable( GL_ALPHA_TEST ); - pglDepthMask( GL_FALSE ); - - gravity = frametime * clgame.movevars.gravity; - scale = 1.0 - (frametime * 0.9); - if( scale < 0.0f ) scale = 0.0f; - - for( p = cl_active_tracers; p; p = p->next ) - { - atten = (p->die - cl.time); - if( atten > 0.1f ) atten = 0.1f; - - VectorScale( p->vel, ( p->ramp * atten ), delta ); - VectorAdd( p->org, delta, end ); - VectorCopy( p->org, start ); - - if( !CL_CullTracer( p, start, end )) - { - vec3_t verts[4], tmp2; - vec3_t tmp, normal; - color24 *pColor; - - // Transform point into screen space - TriWorldToScreen( start, screen ); - TriWorldToScreen( end, screenLast ); - - // build world-space normal to screen-space direction vector - VectorSubtract( screen, screenLast, tmp ); - - // we don't need Z, we're in screen space - tmp[2] = 0; - VectorNormalize( tmp ); - - // build point along noraml line (normal is -y, x) - VectorScale( RI.cull_vup, tmp[0] * gTracerSize[p->type], normal ); - VectorScale( RI.cull_vright, -tmp[1] * gTracerSize[p->type], tmp2 ); - VectorSubtract( normal, tmp2, normal ); - - // compute four vertexes - VectorSubtract( start, normal, verts[0] ); - VectorAdd( start, normal, verts[1] ); - VectorAdd( verts[0], delta, verts[2] ); - VectorAdd( verts[1], delta, verts[3] ); - - pColor = &gTracerColors[p->color]; - pglColor4ub( pColor->r, pColor->g, pColor->b, p->packedColor ); - - pglBegin( GL_QUADS ); - pglTexCoord2f( 0.0f, 0.8f ); - pglVertex3fv( verts[2] ); - pglTexCoord2f( 1.0f, 0.8f ); - pglVertex3fv( verts[3] ); - pglTexCoord2f( 1.0f, 0.0f ); - pglVertex3fv( verts[1] ); - pglTexCoord2f( 0.0f, 0.0f ); - pglVertex3fv( verts[0] ); - pglEnd(); - } - - // evaluate position - VectorMA( p->org, frametime, p->vel, p->org ); - - if( p->type == pt_grav ) - { - p->vel[0] *= scale; - p->vel[1] *= scale; - p->vel[2] -= gravity; - - p->packedColor = 255 * (p->die - cl.time) * 2; - if( p->packedColor > 255 ) p->packedColor = 255; - } - else if( p->type == pt_slowgrav ) - { - p->vel[2] = gravity * 0.05; - } - } - - pglDepthMask( GL_TRUE ); -} /* =============== -CL_DrawParticlesExternal +CL_ReadLineFile_f -allow to draw effects from custom renderer +Optimized version of pointfile - use beams instead of particles =============== */ -void CL_DrawParticlesExternal( const ref_viewpass_t *rvp, qboolean trans_pass, float frametime ) +void CL_ReadLineFile_f( void ) { - ref_instance_t oldRI = RI; + char *afile, *pfile; + vec3_t p1, p2; + int count, modelIndex; + char filename[MAX_QPATH]; + model_t *model; + string token; - memcpy( &oldRI, &RI, sizeof( ref_instance_t )); - R_SetupRefParams( rvp ); - R_SetupFrustum(); - R_SetupGL( false ); // don't touch GL-states + Q_snprintf( filename, sizeof( filename ), "maps/%s.lin", clgame.mapname ); + afile = FS_LoadFile( filename, NULL, false ); - // setup PVS for frame - memcpy( RI.visbytes, tr.visbytes, world.visbytes ); - tr.frametime = frametime; - - if( trans_pass == false ) + if( !afile ) { - CL_DrawBeams( false ); - } - else - { - CL_DrawBeams( true ); - CL_DrawParticles( tr.frametime ); - CL_DrawTracers( tr.frametime ); + Con_Printf( S_ERROR "couldn't open %s\n", filename ); + return; } - // restore internal state - memcpy( &RI, &oldRI, sizeof( ref_instance_t )); + 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 @@ -705,7 +1057,7 @@ void R_EntityParticles( cl_entity_t *ent ) { float angle; float sr, sp, sy, cr, cp, cy; - vec3_t forward; + vec3_t forward; particle_t *p; int i; @@ -720,8 +1072,8 @@ void R_EntityParticles( cl_entity_t *ent ) SinCos( angle, &sp, &cp ); angle = cl.time * cl_avelocities[i][2]; SinCos( angle, &sr, &cr ); - - VectorSet( forward, cp * cy, cp * sy, -sp ); + + VectorSet( forward, cp * cy, cp * sy, -sp ); p->die = cl.time + 0.001f; p->color = 111; // yellow @@ -849,7 +1201,7 @@ void R_RunParticleEffect( const vec3_t org, const vec3_t dir, int color, int cou R_ParticleExplosion( org ); return; } - + for( i = 0; i < count; i++ ) { p = R_AllocParticle( NULL ); @@ -1003,7 +1355,7 @@ void R_LavaSplash( const vec3_t org ) 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; @@ -1121,19 +1473,19 @@ void R_TeleportSplash( const vec3_t org ) { 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 ); @@ -1182,7 +1534,7 @@ void R_RocketTrail( vec3_t start, vec3_t end, int type ) p = R_AllocParticle( NULL ); if( !p ) return; - + p->die = cl.time + 2.0f; switch( type ) @@ -1312,7 +1664,7 @@ void R_ShowLine( const vec3_t start, const vec3_t end ) len = VectorNormalizeLength( dir ); VectorScale( dir, 5.0f, dir ); VectorCopy( start, org ); - + while( len > 0 ) { len -= 5.0f; @@ -1341,8 +1693,8 @@ void R_BulletImpactParticles( const vec3_t pos ) float dist; vec3_t dir; particle_t *p; - - VectorSubtract( pos, RI.vieworg, dir ); + + VectorSubtract( pos, refState.vieworg, dir ); dist = VectorLength( dir ); if( dist > 1000.0f ) dist = 1000.0f; @@ -1407,7 +1759,7 @@ 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; + particle_t *p; int i; VectorScale( dir, speed, vel ); @@ -1503,12 +1855,6 @@ void R_UserTracerParticle( float *org, float *vel, float life, int colorIndex, f 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; @@ -1542,7 +1888,7 @@ void R_SparkStreaks( const vec3_t pos, int count, int velocityMin, int velocityM particle_t *p; vec3_t vel; int i; - + for( i = 0; idie < 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 @@ -1605,7 +2001,7 @@ void CL_ReadPointFile_f( void ) particle_t *p; char filename[64]; string token; - + Q_snprintf( filename, sizeof( filename ), "maps/%s.pts", clgame.mapname ); afile = FS_LoadFile( filename, NULL, false ); @@ -1614,7 +2010,7 @@ void CL_ReadPointFile_f( void ) Con_Printf( S_ERROR "couldn't open %s\n", filename ); return; } - + Con_Printf( "Reading %s...\n", filename ); count = 0; @@ -1635,7 +2031,7 @@ void CL_ReadPointFile_f( void ) org[2] = Q_atof( token ); count++; - + if( !cl_free_particles ) { Con_Printf( S_ERROR "not enough free particles!\n" ); @@ -1649,7 +2045,7 @@ void CL_ReadPointFile_f( void ) p->next = cl_active_particles; cl_active_particles = p; - p->ramp = 0; + p->ramp = 0; p->type = pt_static; p->die = cl.time + 99999; p->color = (-count) & 15; @@ -1662,3 +2058,132 @@ void CL_ReadPointFile_f( void ) 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(); + if( CVAR_TO_BOOL( cl_draw_beams )) + ref.dllFuncs.CL_DrawBeams( fTrans, cl_active_beams ); + + if( fTrans ) + { + R_FreeDeadParticles( &cl_active_particles ); + if( CVAR_TO_BOOL( cl_draw_particles )) + ref.dllFuncs.CL_DrawParticles( time, cl_active_particles, PART_SIZE ); + R_FreeDeadParticles( &cl_active_tracers ); + if( CVAR_TO_BOOL( cl_draw_tracers )) + ref.dllFuncs.CL_DrawTracers( time, cl_active_tracers ); + } +} + +void CL_ThinkParticle( double frametime, 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; + + + if( p->type != pt_clientcustom ) + { + // update position. + VectorMA( p->org, frametime, p->vel, p->org ); + } + + switch( p->type ) + { + case pt_static: + break; + case pt_fire: + p->ramp += time1; + if( p->ramp >= 6.0f ) p->die = -1.0f; + else p->color = ramp3[(int)p->ramp]; + p->vel[2] += grav; + break; + case pt_explode: + p->ramp += time2; + if( p->ramp >= 8.0f ) p->die = -1.0f; + else p->color = ramp1[(int)p->ramp]; + VectorMA( p->vel, dvel, p->vel, p->vel ); + p->vel[2] -= grav; + break; + case pt_explode2: + p->ramp += time3; + if( p->ramp >= 8.0f ) p->die = -1.0f; + else p->color = ramp2[(int)p->ramp]; + VectorMA( p->vel,-frametime, p->vel, p->vel ); + p->vel[2] -= grav; + break; + case pt_blob: + if( p->packedColor == 255 ) + { + // normal blob explosion + VectorMA( p->vel, dvel, p->vel, p->vel ); + p->vel[2] -= grav; + break; + } + case pt_blob2: + if( p->packedColor == 255 ) + { + // normal blob explosion + p->vel[0] -= p->vel[0] * dvel; + p->vel[1] -= p->vel[1] * dvel; + p->vel[2] -= grav; + } + else + { + p->ramp += time2; + if( p->ramp >= 9.0f ) p->ramp = 0.0f; + p->color = gSparkRamp[(int)p->ramp]; + VectorMA( p->vel, -frametime * 0.5f, p->vel, p->vel ); + p->type = COM_RandomLong( 0, 3 ) ? pt_blob : pt_blob2; + p->vel[2] -= grav * 5.0f; + } + break; + case pt_grav: + p->vel[2] -= grav * 20.0f; + break; + case pt_slowgrav: + p->vel[2] -= grav; + break; + case pt_vox_grav: + p->vel[2] -= grav * 8.0f; + break; + case pt_vox_slowgrav: + p->vel[2] -= grav * 4.0f; + break; + case pt_clientcustom: + if( p->callback ) + p->callback( p, frametime ); + break; + } +} + diff --git a/engine/client/cl_frame.c b/engine/client/cl_frame.c index bf964fc6..bfd6750e 100644 --- a/engine/client/cl_frame.c +++ b/engine/client/cl_frame.c @@ -17,7 +17,6 @@ GNU General Public License for more details. #include "client.h" #include "net_encode.h" #include "entity_types.h" -#include "gl_local.h" #include "pm_local.h" #include "cl_tent.h" #include "studio.h" @@ -226,6 +225,33 @@ void CL_UpdateLatchedVars( cl_entity_t *ent ) memcpy( ent->latched.prevblending, ent->prevstate.blending, sizeof( ent->latched.prevblending )); } +/* +==================== +CL_GetStudioEstimatedFrame + +==================== +*/ +float CL_GetStudioEstimatedFrame( cl_entity_t *ent ) +{ + studiohdr_t *pstudiohdr; + mstudioseqdesc_t *pseqdesc; + int sequence; + + if( ent->model != NULL && ent->model->type == mod_studio ) + { + pstudiohdr = (studiohdr_t *)Mod_StudioExtradata( ent->model ); + + if( pstudiohdr ) + { + sequence = bound( 0, ent->curstate.sequence, pstudiohdr->numseq - 1 ); + pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + sequence; + return ref.dllFuncs.R_StudioEstimateFrame( ent, pseqdesc ); + } + } + + return 0; +} + /* ==================== CL_ResetLatchedVars @@ -939,10 +965,10 @@ 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( !R_AddEntity( ent, entityType )) + else if( !ref.dllFuncs.R_AddEntity( ent, entityType )) { return false; } @@ -1191,7 +1217,7 @@ void CL_LinkPacketEntities( frame_t *frame ) if( ent->model->type == mod_studio ) { if( interpolate && FBitSet( host.features, ENGINE_COMPUTE_STUDIO_LERP )) - R_StudioLerpMovement( ent, cl.time, ent->origin, ent->angles ); + ref.dllFuncs.R_StudioLerpMovement( ent, cl.time, ent->origin, ent->angles ); } } @@ -1262,8 +1288,6 @@ void CL_EmitEntities( void ) { if( cl.paused ) return; // don't waste time - R_ClearScene (); - // not in server yet, no entities to redraw if( cls.state != ca_active || !cl.validsequence ) return; @@ -1273,7 +1297,7 @@ void CL_EmitEntities( void ) return; // animate lightestyles - CL_RunLightStyles (); + ref.dllFuncs.CL_RunLightStyles (); // decay dynamic lights CL_DecayLights (); @@ -1284,9 +1308,7 @@ void CL_EmitEntities( void ) // set client ideal pitch when mlook is disabled CL_SetIdealPitch (); - // clear the scene befor start new frame - if( clgame.drawFuncs.R_ClearScene != NULL ) - clgame.drawFuncs.R_ClearScene(); + ref.dllFuncs.R_ClearScene (); // link all the visible clients first CL_LinkPlayers ( &cl.frames[cl.parsecountmod] ); @@ -1330,7 +1352,7 @@ qboolean CL_GetEntitySpatialization( channel_t *ch ) if(( ch->entnum - 1 ) == cl.playernum ) { - VectorCopy( RI.vieworg, ch->origin ); + VectorCopy( refState.vieworg, ch->origin ); return true; } diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index 7494c8e0..fc158583 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -25,7 +25,6 @@ GNU General Public License for more details. #include "input.h" #include "shake.h" #include "sprite.h" -#include "gl_local.h" #include "library.h" #include "vgui_draw.h" #include "sound.h" // SND_STOP_LOOPING @@ -278,18 +277,18 @@ static int CL_AdjustXPos( float x, int width, int totalWidth ) if( x == -1 ) { - xPos = ( glState.width - width ) * 0.5f; + xPos = ( refState.width - width ) * 0.5f; } else { if ( x < 0 ) - xPos = (1.0f + x) * glState.width - totalWidth; // Alight right + xPos = (1.0f + x) * refState.width - totalWidth; // Alight right else // align left - xPos = x * glState.width; + xPos = x * refState.width; } - if( xPos + width > glState.width ) - xPos = glState.width - width; + if( xPos + width > refState.width ) + xPos = refState.width - width; else if( xPos < 0 ) xPos = 0; @@ -309,19 +308,19 @@ static int CL_AdjustYPos( float y, int height ) if( y == -1 ) // centered? { - yPos = ( glState.height - height ) * 0.5f; + yPos = ( refState.height - height ) * 0.5f; } else { // Alight bottom? if( y < 0 ) - yPos = (1.0f + y) * glState.height - height; // Alight bottom + yPos = (1.0f + y) * refState.height - height; // Alight bottom else // align top - yPos = y * glState.height; + yPos = y * refState.height; } - if( yPos + height > glState.height ) - yPos = glState.height - height; + if( yPos + height > refState.height ) + yPos = refState.height - height; else if( yPos < 0 ) yPos = 0; @@ -383,8 +382,8 @@ static void SPR_AdjustSize( float *x, float *y, float *w, float *h ) if( !x && !y && !w && !h ) return; // scale for screen sizes - xscale = glState.width / (float)clgame.scrInfo.iWidth; - yscale = glState.height / (float)clgame.scrInfo.iHeight; + xscale = refState.width / (float)clgame.scrInfo.iWidth; + yscale = refState.height / (float)clgame.scrInfo.iHeight; if( x ) *x *= xscale; if( y ) *y *= yscale; @@ -407,8 +406,8 @@ void PicAdjustSize( float *x, float *y, float *w, float *h ) if( !x && !y && !w && !h ) return; // scale for screen sizes - xscale = glState.width / (float)clgame.scrInfo.iWidth; - yscale = glState.height / (float)clgame.scrInfo.iHeight; + xscale = refState.width / (float)clgame.scrInfo.iWidth; + yscale = refState.height / (float)clgame.scrInfo.iHeight; if( x ) *x *= xscale; if( y ) *y *= yscale; @@ -482,7 +481,7 @@ static void SPR_DrawGeneric( int frame, float x, float y, float width, float hei int w, h; // assume we get sizes from image - R_GetSpriteParms( &w, &h, NULL, frame, clgame.ds.pSprite ); + ref.dllFuncs.R_GetSpriteParms( &w, &h, NULL, frame, clgame.ds.pSprite ); width = w; height = h; @@ -520,10 +519,9 @@ static void SPR_DrawGeneric( int frame, float x, float y, float width, float hei // scale for screen sizes SPR_AdjustSize( &x, &y, &width, &height ); - texnum = R_GetSpriteTexture( clgame.ds.pSprite, frame ); - pglColor4ubv( clgame.ds.spriteColor ); - pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, texnum ); + texnum = ref.dllFuncs.R_GetSpriteTexture( clgame.ds.pSprite, frame ); + ref.dllFuncs.Color4ub( clgame.ds.spriteColor[0], clgame.ds.spriteColor[1], clgame.ds.spriteColor[2], clgame.ds.spriteColor[3] ); + ref.dllFuncs.R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, texnum ); } /* @@ -581,7 +579,7 @@ void CL_DrawCenterPrint( void ) for( j = 0; j < lineLength; j++ ) { - if( x >= 0 && y >= 0 && x <= glState.width ) + if( x >= 0 && y >= 0 && x <= refState.width ) x += Con_DrawCharacter( x, y, line[j], colorDefault ); } y += charHeight; @@ -629,13 +627,14 @@ void CL_DrawScreenFade( void ) iFadeAlpha = bound( 0, iFadeAlpha, sf->fadealpha ); } - pglColor4ub( sf->fader, sf->fadeg, sf->fadeb, iFadeAlpha ); + ref.dllFuncs.Color4ub( sf->fader, sf->fadeg, sf->fadeb, iFadeAlpha ); if( sf->fadeFlags & FFADE_MODULATE ) - GL_SetRenderMode( kRenderTransAdd ); - else GL_SetRenderMode( kRenderTransTexture ); - R_DrawStretchPic( 0, 0, glState.width, glState.height, 0, 0, 1, 1, tr.whiteTexture ); - pglColor4ub( 255, 255, 255, 255 ); + ref.dllFuncs.GL_SetRenderMode( kRenderTransAdd ); + else ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture ); + ref.dllFuncs.R_DrawStretchPic( 0, 0, refState.width, refState.height, 0, 0, 1, 1, + ref.dllFuncs.R_GetBuiltinTexture( REF_WHITE_TEXTURE )); + ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); } /* @@ -913,10 +912,10 @@ void CL_DrawCrosshair( void ) vec3_t forward; vec3_t point, screen; - VectorAdd( RI.viewangles, cl.crosshairangle, angles ); + VectorAdd( refState.viewangles, cl.crosshairangle, angles ); AngleVectors( angles, forward, NULL, NULL ); - VectorAdd( RI.vieworg, forward, point ); - R_WorldToScreen( point, screen ); + VectorAdd( refState.vieworg, forward, point ); + ref.dllFuncs.WorldToScreen( point, screen ); x += ( clgame.viewport[2] >> 1 ) * screen[0] + 0.5f; y += ( clgame.viewport[3] >> 1 ) * screen[1] + 0.5f; @@ -950,8 +949,8 @@ static void CL_DrawLoading( float percent ) x = ( clgame.scrInfo.iWidth - width ) >> 1; y = ( clgame.scrInfo.iHeight - height) >> 1; - xscale = glState.width / (float)clgame.scrInfo.iWidth; - yscale = glState.height / (float)clgame.scrInfo.iHeight; + xscale = refState.width / (float)clgame.scrInfo.iWidth; + yscale = refState.height / (float)clgame.scrInfo.iHeight; x *= xscale; y *= yscale; @@ -959,26 +958,26 @@ static void CL_DrawLoading( float percent ) height *= yscale; if( cl_allow_levelshots->value ) - { - pglColor4ub( 128, 128, 128, 255 ); - GL_SetRenderMode( kRenderTransTexture ); - R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.loadingBar ); + { + ref.dllFuncs.Color4ub( 128, 128, 128, 255 ); + ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture ); + ref.dllFuncs.R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.loadingBar ); step = (float)width / 100.0f; right = (int)ceil( percent * step ); s2 = (float)right / width; width = right; - pglColor4ub( 208, 152, 0, 255 ); - GL_SetRenderMode( kRenderTransTexture ); - R_DrawStretchPic( x, y, width, height, 0, 0, s2, 1, cls.loadingBar ); - pglColor4ub( 255, 255, 255, 255 ); + ref.dllFuncs.Color4ub( 208, 152, 0, 255 ); + ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture ); + ref.dllFuncs.R_DrawStretchPic( x, y, width, height, 0, 0, s2, 1, cls.loadingBar ); + ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); } else { - pglColor4ub( 255, 255, 255, 255 ); - GL_SetRenderMode( kRenderTransTexture ); - R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.loadingBar ); + ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); + ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture ); + ref.dllFuncs.R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.loadingBar ); } } @@ -998,17 +997,17 @@ static void CL_DrawPause( void ) x = ( clgame.scrInfo.iWidth - width ) >> 1; y = ( clgame.scrInfo.iHeight - height) >> 1; - xscale = glState.width / (float)clgame.scrInfo.iWidth; - yscale = glState.height / (float)clgame.scrInfo.iHeight; + xscale = refState.width / (float)clgame.scrInfo.iWidth; + yscale = refState.height / (float)clgame.scrInfo.iHeight; x *= xscale; y *= yscale; width *= xscale; height *= yscale; - pglColor4ub( 255, 255, 255, 255 ); - GL_SetRenderMode( kRenderTransTexture ); - R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.pauseIcon ); + ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); + ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture ); + ref.dllFuncs.R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.pauseIcon ); } void CL_DrawHUD( int state ) @@ -1112,7 +1111,7 @@ void CL_ClearWorld( void ) world->model = cl.worldmodel; world->index = 0; - clgame.ds.cullMode = GL_FRONT; + clgame.ds.cullMode = TRI_FRONT; clgame.numStatics = 0; } @@ -1136,20 +1135,12 @@ void CL_InitEdicts( void ) clgame.remap_info = (remap_info_t **)Mem_Calloc( clgame.mempool, sizeof( remap_info_t* ) * clgame.maxRemapInfos ); } - if( clgame.drawFuncs.R_ProcessEntData != NULL ) - { - // let the client.dll free custom data - clgame.drawFuncs.R_ProcessEntData( true ); - } + ref.dllFuncs.R_ProcessEntData( true ); } void CL_FreeEdicts( void ) { - if( clgame.drawFuncs.R_ProcessEntData != NULL ) - { - // let the client.dll free custom data - clgame.drawFuncs.R_ProcessEntData( false ); - } + ref.dllFuncs.R_ProcessEntData( false ); if( clgame.entities ) Mem_Free( clgame.entities ); @@ -1227,7 +1218,7 @@ static qboolean CL_LoadHudSprite( const char *szSpriteName, model_t *m_pSprite, else { Con_Reportf( S_ERROR "Could not load HUD sprite %s\n", szSpriteName ); - Mod_UnloadSpriteModel( m_pSprite ); + Mod_FreeModel( m_pSprite ); return false; } } @@ -1236,14 +1227,18 @@ static qboolean CL_LoadHudSprite( const char *szSpriteName, model_t *m_pSprite, ASSERT( buf != NULL ); if( type == SPR_MAPSPRITE ) - Mod_LoadMapSprite( m_pSprite, buf, size, &loaded ); - else Mod_LoadSpriteModel( m_pSprite, buf, &loaded, texFlags ); + ref.dllFuncs.Mod_LoadMapSprite( m_pSprite, buf, size, &loaded ); + else + { + Mod_LoadSpriteModel( m_pSprite, buf, &loaded, texFlags ); + ref.dllFuncs.Mod_ProcessRenderData( m_pSprite, true, buf ); + } Mem_Free( buf ); if( !loaded ) { - Mod_UnloadSpriteModel( m_pSprite ); + Mod_FreeModel( m_pSprite ); return false; } @@ -1399,7 +1394,7 @@ static int pfnSPR_Frames( HSPRITE hPic ) { int numFrames; - R_GetSpriteParms( NULL, NULL, &numFrames, 0, CL_GetSpritePointer( hPic )); + ref.dllFuncs.R_GetSpriteParms( NULL, NULL, &numFrames, 0, CL_GetSpritePointer( hPic )); return numFrames; } @@ -1414,7 +1409,7 @@ static int pfnSPR_Height( HSPRITE hPic, int frame ) { int sprHeight; - R_GetSpriteParms( NULL, &sprHeight, NULL, frame, CL_GetSpritePointer( hPic )); + ref.dllFuncs.R_GetSpriteParms( NULL, &sprHeight, NULL, frame, CL_GetSpritePointer( hPic )); return sprHeight; } @@ -1429,7 +1424,7 @@ static int pfnSPR_Width( HSPRITE hPic, int frame ) { int sprWidth; - R_GetSpriteParms( &sprWidth, NULL, NULL, frame, CL_GetSpritePointer( hPic )); + ref.dllFuncs.R_GetSpriteParms( &sprWidth, NULL, NULL, frame, CL_GetSpritePointer( hPic )); return sprWidth; } @@ -1457,8 +1452,7 @@ pfnSPR_Draw */ static void pfnSPR_Draw( int frame, int x, int y, const wrect_t *prc ) { - pglDisable( GL_BLEND ); - + ref.dllFuncs.GL_SetRenderMode( kRenderNormal ); SPR_DrawGeneric( frame, x, y, -1, -1, prc ); } @@ -1470,14 +1464,21 @@ pfnSPR_DrawHoles */ static void pfnSPR_DrawHoles( int frame, int x, int y, const wrect_t *prc ) { +#if 1 // REFTODO + ref.dllFuncs.GL_SetRenderMode( kRenderTransColor ); +#else pglEnable( GL_ALPHA_TEST ); pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); pglEnable( GL_BLEND ); - +#endif SPR_DrawGeneric( frame, x, y, -1, -1, prc ); +#if 1 + ref.dllFuncs.GL_SetRenderMode( kRenderNormal ); +#else pglDisable( GL_ALPHA_TEST ); pglDisable( GL_BLEND ); +#endif } /* @@ -1488,12 +1489,20 @@ pfnSPR_DrawAdditive */ static void pfnSPR_DrawAdditive( int frame, int x, int y, const wrect_t *prc ) { +#if 1 // REFTODO + ref.dllFuncs.GL_SetRenderMode( kRenderTransAdd ); +#else pglEnable( GL_BLEND ); pglBlendFunc( GL_ONE, GL_ONE ); +#endif SPR_DrawGeneric( frame, x, y, -1, -1, prc ); +#if 1 // REFTODO + ref.dllFuncs.GL_SetRenderMode( kRenderNormal ); +#else pglDisable( GL_BLEND ); +#endif } /* @@ -1603,6 +1612,9 @@ void CL_FillRGBA( int x, int y, int w, int h, int r, int g, int b, int a ) SPR_AdjustSize( &_x, &_y, &_w, &_h ); +#if 1 + ref.dllFuncs.FillRGBA( _x, _y, _w, _h, r, g, b, a ); +#else pglDisable( GL_TEXTURE_2D ); pglEnable( GL_BLEND ); pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); @@ -1619,6 +1631,7 @@ void CL_FillRGBA( int x, int y, int w, int h, int r, int g, int b, int a ) pglColor3f( 1.0f, 1.0f, 1.0f ); pglEnable( GL_TEXTURE_2D ); pglDisable( GL_BLEND ); +#endif } /* @@ -1638,14 +1651,14 @@ int CL_GetScreenInfo( SCREENINFO *pscrinfo ) if( scale_factor && scale_factor != 1.0f) { - clgame.scrInfo.iWidth = (float)glState.width / scale_factor; - clgame.scrInfo.iHeight = (float)glState.height / scale_factor; + clgame.scrInfo.iWidth = (float)refState.width / scale_factor; + clgame.scrInfo.iHeight = (float)refState.height / scale_factor; clgame.scrInfo.iFlags |= SCRINFO_STRETCHED; } else { - clgame.scrInfo.iWidth = glState.width; - clgame.scrInfo.iHeight = glState.height; + clgame.scrInfo.iWidth = refState.width; + clgame.scrInfo.iHeight = refState.height; clgame.scrInfo.iFlags &= ~SCRINFO_STRETCHED; } @@ -2066,7 +2079,7 @@ pfnIsNoClipping ============= */ -int pfnIsNoClipping( void ) +static int pfnIsNoClipping( void ) { return ( cl.frames[cl.parsecountmod].playerstate[cl.playernum].movetype == MOVETYPE_NOCLIP ); } @@ -2077,7 +2090,7 @@ pfnGetViewModel ============= */ -static cl_entity_t* pfnGetViewModel( void ) +cl_entity_t* CL_GetViewModel( void ) { return &clgame.viewent; } @@ -2516,7 +2529,7 @@ pfnTraceSurface ============= */ -static struct msurface_s *pfnTraceSurface( int ground, float *vstart, float *vend ) +struct msurface_s *pfnTraceSurface( int ground, float *vstart, float *vend ) { physent_t *pe; @@ -2533,7 +2546,7 @@ pfnGetMovevars ============= */ -static movevars_t *pfnGetMoveVars( void ) +movevars_t *pfnGetMoveVars( void ) { return &clgame.movevars; } @@ -2628,7 +2641,7 @@ pfnGetScreenFade ============= */ -static void pfnGetScreenFade( struct screenfade_s *fade ) +void pfnGetScreenFade( struct screenfade_s *fade ) { if( fade ) *fade = clgame.fade; } @@ -2848,8 +2861,10 @@ pfnSPR_DrawGeneric */ static void GAME_EXPORT pfnSPR_DrawGeneric( int frame, int x, int y, const wrect_t *prc, int blendsrc, int blenddst, int width, int height ) { +#if 0 // REFTODO: pglEnable( GL_BLEND ); pglBlendFunc( blendsrc, blenddst ); // g-cont. are params is valid? +#endif SPR_DrawGeneric( frame, x, y, width, height, prc ); } @@ -3018,6 +3033,9 @@ void GAME_EXPORT CL_FillRGBABlend( int x, int y, int w, int h, int r, int g, int SPR_AdjustSize( &_x, &_y, &_w, &_h ); +#if 1 // REFTODO: + ref.dllFuncs.FillRGBABlend( _x, _y, _w, _h, r, g, b, a ); +#else pglDisable( GL_TEXTURE_2D ); pglEnable( GL_BLEND ); pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); @@ -3034,6 +3052,7 @@ void GAME_EXPORT CL_FillRGBABlend( int x, int y, int w, int h, int r, int g, int pglColor3f( 1.0f, 1.0f, 1.0f ); pglEnable( GL_TEXTURE_2D ); pglDisable( GL_BLEND ); +#endif } /* @@ -3078,111 +3097,31 @@ char *pfnParseFile( char *data, char *token ) /* ================= -TriApi implementation +TriAPI implementation ================= */ /* -============= +================= TriRenderMode - -set rendermode -============= +================= */ void TriRenderMode( int mode ) { - switch( mode ) - { - case kRenderNormal: - pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - pglDisable( GL_BLEND ); - pglDepthMask( GL_TRUE ); - break; - case kRenderTransAlpha: - pglEnable( GL_BLEND ); - pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - pglDepthMask( GL_FALSE ); - break; - case kRenderTransColor: - case kRenderTransTexture: - pglEnable( GL_BLEND ); - pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - break; - case kRenderGlow: - case kRenderTransAdd: - pglBlendFunc( GL_SRC_ALPHA, GL_ONE ); - pglEnable( GL_BLEND ); - pglDepthMask( GL_FALSE ); - break; - } - clgame.ds.renderMode = mode; + ref.dllFuncs.TriRenderMode( mode ); } /* -============= -TriBegin - -begin triangle sequence -============= -*/ -void TriBegin( int mode ) -{ - switch( mode ) - { - case TRI_POINTS: - mode = GL_POINTS; - break; - case TRI_TRIANGLES: - mode = GL_TRIANGLES; - break; - case TRI_TRIANGLE_FAN: - mode = GL_TRIANGLE_FAN; - break; - case TRI_QUADS: - mode = GL_QUADS; - break; - case TRI_LINES: - mode = GL_LINES; - break; - case TRI_TRIANGLE_STRIP: - mode = GL_TRIANGLE_STRIP; - break; - case TRI_QUAD_STRIP: - mode = GL_QUAD_STRIP; - break; - case TRI_POLYGON: - default: mode = GL_POLYGON; - break; - } - - pglBegin( mode ); -} - -/* -============= -TriEnd - -draw triangle sequence -============= -*/ -void TriEnd( void ) -{ - pglEnd(); -} - -/* -============= +================= TriColor4f - -============= +================= */ void TriColor4f( float r, float g, float b, float a ) { if( clgame.ds.renderMode == kRenderTransAlpha ) - pglColor4ub( r * 255.9f, g * 255.9f, b * 255.9f, a * 255.0f ); - else pglColor4f( r * a, g * a, b * a, 1.0 ); + ref.dllFuncs.Color4ub( r * 255.9f, g * 255.9f, b * 255.9f, a * 255.0f ); + else ref.dllFuncs.Color4f( r * a, g * a, b * a, 1.0 ); clgame.ds.triRGBA[0] = r; clgame.ds.triRGBA[1] = g; @@ -3193,7 +3132,6 @@ void TriColor4f( float r, float g, float b, float a ) /* ============= TriColor4ub - ============= */ void TriColor4ub( byte r, byte g, byte b, byte a ) @@ -3203,46 +3141,12 @@ void TriColor4ub( byte r, byte g, byte b, byte a ) clgame.ds.triRGBA[2] = b * (1.0f / 255.0f); clgame.ds.triRGBA[3] = a * (1.0f / 255.0f); - pglColor4f( clgame.ds.triRGBA[0], clgame.ds.triRGBA[1], clgame.ds.triRGBA[2], 1.0f ); -} - -/* -============= -TriTexCoord2f - -============= -*/ -void TriTexCoord2f( float u, float v ) -{ - pglTexCoord2f( u, v ); -} - -/* -============= -TriVertex3fv - -============= -*/ -void TriVertex3fv( const float *v ) -{ - pglVertex3fv( v ); -} - -/* -============= -TriVertex3f - -============= -*/ -void TriVertex3f( float x, float y, float z ) -{ - pglVertex3f( x, y, z ); + ref.dllFuncs.Color4f( clgame.ds.triRGBA[0], clgame.ds.triRGBA[1], clgame.ds.triRGBA[2], 1.0f ); } /* ============= TriBrightness - ============= */ void TriBrightness( float brightness ) @@ -3253,30 +3157,88 @@ void TriBrightness( float brightness ) g = clgame.ds.triRGBA[1] * clgame.ds.triRGBA[3] * brightness; b = clgame.ds.triRGBA[2] * clgame.ds.triRGBA[3] * brightness; - pglColor4f( r, g, b, 1.0f ); + ref.dllFuncs.Color4f( r, g, b, 1.0f ); } /* ============= TriCullFace - ============= */ -void TriCullFace( TRICULLSTYLE mode ) +void TriCullFace( TRICULLSTYLE style ) { - switch( mode ) - { - case TRI_FRONT: - clgame.ds.cullMode = GL_FRONT; - break; - default: - clgame.ds.cullMode = GL_NONE; - break; - } - - GL_Cull( clgame.ds.cullMode ); + clgame.ds.cullMode = style; + ref.dllFuncs.CullFace( style ); } +/* +============= +TriWorldToScreen +convert world coordinates (x,y,z) into screen (x, y) +============= +*/ +int TriWorldToScreen( const float *world, float *screen ) +{ + int retval; + + retval = ref.dllFuncs.WorldToScreen( world, screen ); + + screen[0] = 0.5f * screen[0] * (float)clgame.viewport[2]; + screen[1] = -0.5f * screen[1] * (float)clgame.viewport[3]; + screen[0] += 0.5f * (float)clgame.viewport[2]; + screen[1] += 0.5f * (float)clgame.viewport[3]; + + return retval; +} + +/* +============= +TriBoxInPVS + +check box in pvs (absmin, absmax) +============= +*/ +int TriBoxInPVS( float *mins, float *maxs ) +{ + return Mod_BoxVisible( mins, maxs, ref.dllFuncs.Mod_GetCurrentVis( )); +} + +/* +============= +TriLightAtPoint +NOTE: dlights are ignored +============= +*/ +void TriLightAtPoint( float *pos, float *value ) +{ + colorVec vLightColor; + + if( !pos || !value ) return; + + vLightColor = ref.dllFuncs.R_LightPoint( pos ); + + value[0] = vLightColor.r; + value[1] = vLightColor.g; + value[2] = vLightColor.b; +} + +/* +============= +TriColor4fRendermode +Heavy legacy of Quake... +============= +*/ +void TriColor4fRendermode( float r, float g, float b, float a, int rendermode ) +{ + if( clgame.ds.renderMode == kRenderTransAlpha ) + { + clgame.ds.triRGBA[3] = a / 255.0f; + ref.dllFuncs.Color4f( r, g, b, a ); + } + else ref.dllFuncs.Color4f( r * a, g * a, b * a, 1.0f ); +} + + /* ============= TriSpriteTexture @@ -3288,153 +3250,14 @@ int TriSpriteTexture( model_t *pSpriteModel, int frame ) { int gl_texturenum; - if(( gl_texturenum = R_GetSpriteTexture( pSpriteModel, frame )) == 0 ) + if(( gl_texturenum = ref.dllFuncs.R_GetSpriteTexture( pSpriteModel, frame )) <= 0 ) return 0; - if( gl_texturenum <= 0 || gl_texturenum > MAX_TEXTURES ) - gl_texturenum = tr.defaultTexture; - - GL_Bind( XASH_TEXTURE0, gl_texturenum ); + ref.dllFuncs.GL_Bind( XASH_TEXTURE0, gl_texturenum ); return 1; } -/* -============= -TriWorldToScreen - -convert world coordinates (x,y,z) into screen (x, y) -============= -*/ -int TriWorldToScreen( float *world, float *screen ) -{ - int retval; - - retval = R_WorldToScreen( world, screen ); - - screen[0] = 0.5f * screen[0] * (float)clgame.viewport[2]; - screen[1] = -0.5f * screen[1] * (float)clgame.viewport[3]; - screen[0] += 0.5f * (float)clgame.viewport[2]; - screen[1] += 0.5f * (float)clgame.viewport[3]; - - return retval; -} - -/* -============= -TriFog - -enables global fog on the level -============= -*/ -void TriFog( float flFogColor[3], float flStart, float flEnd, int bOn ) -{ - // overrided by internal fog - if( RI.fogEnabled ) return; - RI.fogCustom = bOn; - - // check for invalid parms - if( flEnd <= flStart ) - { - RI.fogCustom = false; - pglDisable( GL_FOG ); - return; - } - - if( RI.fogCustom ) - pglEnable( GL_FOG ); - else pglDisable( GL_FOG ); - - // copy fog params - RI.fogColor[0] = flFogColor[0] / 255.0f; - RI.fogColor[1] = flFogColor[1] / 255.0f; - RI.fogColor[2] = flFogColor[2] / 255.0f; - RI.fogStart = flStart; - RI.fogColor[3] = 1.0f; - RI.fogDensity = 0.0f; - RI.fogSkybox = true; - RI.fogEnd = flEnd; - - pglFogi( GL_FOG_MODE, GL_LINEAR ); - pglFogfv( GL_FOG_COLOR, RI.fogColor ); - pglFogf( GL_FOG_START, RI.fogStart ); - pglFogf( GL_FOG_END, RI.fogEnd ); - pglHint( GL_FOG_HINT, GL_NICEST ); -} - -/* -============= -TriGetMatrix - -very strange export -============= -*/ -void TriGetMatrix( const int pname, float *matrix ) -{ - pglGetFloatv( pname, matrix ); -} - -/* -============= -TriBoxInPVS - -check box in pvs (absmin, absmax) -============= -*/ -int TriBoxInPVS( float *mins, float *maxs ) -{ - return Mod_BoxVisible( mins, maxs, Mod_GetCurrentVis( )); -} - -/* -============= -TriLightAtPoint - -NOTE: dlights are ignored -============= -*/ -void TriLightAtPoint( float *pos, float *value ) -{ - colorVec vLightColor; - - if( !pos || !value ) return; - - vLightColor = R_LightPoint( pos ); - - value[0] = vLightColor.r; - value[1] = vLightColor.g; - value[2] = vLightColor.b; -} - -/* -============= -TriColor4fRendermode - -Heavy legacy of Quake... -============= -*/ -void TriColor4fRendermode( float r, float g, float b, float a, int rendermode ) -{ - if( clgame.ds.renderMode == kRenderTransAlpha ) - { - clgame.ds.triRGBA[3] = a / 255.0f; - pglColor4f( r, g, b, a ); - } - else pglColor4f( r * a, g * a, b * a, 1.0f ); -} - -/* -============= -TriForParams - -============= -*/ -void TriFogParams( float flDensity, int iFogSkybox ) -{ - RI.fogDensity = flDensity; - RI.fogSkybox = iFogSkybox; -} - /* ================= DemoApi implementation @@ -3788,35 +3611,14 @@ float Voice_GetControlFloat( VoiceTweakControl iControl ) { return 1.0f; } + static void GAME_EXPORT VGui_ViewportPaintBackground( int extents[4] ) { // stub } // shared between client and server -triangleapi_t gTriApi = -{ - TRI_API_VERSION, - TriRenderMode, - TriBegin, - TriEnd, - TriColor4f, - TriColor4ub, - TriTexCoord2f, - TriVertex3fv, - TriVertex3f, - TriBrightness, - TriCullFace, - TriSpriteTexture, - R_WorldToScreen, // NOTE: XPROJECT, YPROJECT should be done in client.dll - TriFog, - R_ScreenToWorld, - TriGetMatrix, - TriBoxInPVS, - TriLightAtPoint, - TriColor4fRendermode, - TriFogParams, -}; +triangleapi_t gTriApi; static efx_api_t gEfxApi = { @@ -4017,7 +3819,7 @@ static cl_enginefunc_t gEngfuncs = Platform_GetMousePos, pfnIsNoClipping, CL_GetLocalPlayer, - pfnGetViewModel, + CL_GetViewModel, CL_GetEntityByIndex, pfnGetClientTime, pfnCalcShake, @@ -4236,6 +4038,7 @@ qboolean CL_LoadProgs( const char *name ) if( !R_InitRenderAPI()) // Xash3D extension Con_Reportf( S_WARN "CL_LoadProgs: couldn't get render API\n" ); + if( !Mobile_Init() ) // Xash3D FWGS extension: mobile interface Con_Reportf( S_WARN "CL_LoadProgs: couldn't get mobility API\n" ); @@ -4245,13 +4048,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_gameui.c b/engine/client/cl_gameui.c index c288d7a9..1604ba60 100644 --- a/engine/client/cl_gameui.c +++ b/engine/client/cl_gameui.c @@ -16,10 +16,10 @@ GNU General Public License for more details. #include "common.h" #include "client.h" #include "const.h" -#include "gl_local.h" #include "library.h" #include "input.h" #include "server.h" // !!svgame.hInstance +#include "vid_common.h" static MENUAPI GetMenuAPI; static ADDTOUCHBUTTONTOLIST pfnAddTouchButtonToList; @@ -203,7 +203,7 @@ static void UI_DrawLogo( const char *filename, float x, float y, float width, fl redraw = true; } - R_DrawStretchRaw( x, y, width, height, gameui.logo_xres, gameui.logo_yres, cin_data, redraw ); + ref.dllFuncs.R_DrawStretchRaw( x, y, width, height, gameui.logo_xres, gameui.logo_yres, cin_data, redraw ); } static int UI_GetLogoWidth( void ) @@ -360,8 +360,8 @@ static void PIC_DrawGeneric( float x, float y, float width, float height, const return; PicAdjustSize( &x, &y, &width, &height ); - R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, gameui.ds.gl_texturenum ); - pglColor4ub( 255, 255, 255, 255 ); + ref.dllFuncs.R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, gameui.ds.gl_texturenum ); + ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); } /* @@ -390,7 +390,7 @@ static HIMAGE pfnPIC_Load( const char *szPicName, const byte *image_buf, int ima SetBits( flags, TF_IMAGE ); Image_SetForceFlags( IL_LOAD_DECAL ); // allow decal images for menu - tx = GL_LoadTexture( szPicName, image_buf, image_size, flags ); + tx = ref.dllFuncs.GL_LoadTexture( szPicName, image_buf, image_size, flags ); Image_ClearForceFlags(); return tx; @@ -439,7 +439,7 @@ void pfnPIC_Set( HIMAGE hPic, int r, int g, int b, int a ) g = bound( 0, g, 255 ); b = bound( 0, b, 255 ); a = bound( 0, a, 255 ); - pglColor4ub( r, g, b, a ); + ref.dllFuncs.Color4ub( r, g, b, a ); } /* @@ -450,7 +450,7 @@ pfnPIC_Draw */ void pfnPIC_Draw( int x, int y, int width, int height, const wrect_t *prc ) { - GL_SetRenderMode( kRenderNormal ); + ref.dllFuncs.GL_SetRenderMode( kRenderNormal ); PIC_DrawGeneric( x, y, width, height, prc ); } @@ -462,7 +462,7 @@ pfnPIC_DrawTrans */ void pfnPIC_DrawTrans( int x, int y, int width, int height, const wrect_t *prc ) { - GL_SetRenderMode( kRenderTransTexture ); + ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture ); PIC_DrawGeneric( x, y, width, height, prc ); } @@ -474,7 +474,7 @@ pfnPIC_DrawHoles */ void pfnPIC_DrawHoles( int x, int y, int width, int height, const wrect_t *prc ) { - GL_SetRenderMode( kRenderTransAlpha ); + ref.dllFuncs.GL_SetRenderMode( kRenderTransAlpha ); PIC_DrawGeneric( x, y, width, height, prc ); } @@ -486,7 +486,7 @@ pfnPIC_DrawAdditive */ void pfnPIC_DrawAdditive( int x, int y, int width, int height, const wrect_t *prc ) { - GL_SetRenderMode( kRenderTransAdd ); + ref.dllFuncs.GL_SetRenderMode( kRenderTransAdd ); PIC_DrawGeneric( x, y, width, height, prc ); } @@ -553,10 +553,10 @@ static void pfnFillRGBA( int x, int y, int width, int height, int r, int g, int g = bound( 0, g, 255 ); b = bound( 0, b, 255 ); a = bound( 0, a, 255 ); - pglColor4ub( r, g, b, a ); - GL_SetRenderMode( kRenderTransTexture ); - R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, tr.whiteTexture ); - pglColor4ub( 255, 255, 255, 255 ); + ref.dllFuncs.Color4ub( r, g, b, a ); + ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture ); + ref.dllFuncs.R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, ref.dllFuncs.R_GetBuiltinTexture( REF_WHITE_TEXTURE ) ); + ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); } /* @@ -614,7 +614,7 @@ static void pfnDrawCharacter( int ix, int iy, int iwidth, int iheight, int ch, i color[0] = (ulRGBA & 0xFF0000) >> 16; color[1] = (ulRGBA & 0xFF00) >> 8; color[2] = (ulRGBA & 0xFF) >> 0; - pglColor4ubv( color ); + ref.dllFuncs.Color4ub( color[0], color[1], color[2], color[3] ); col = (ch & 15) * 0.0625f + (0.5f / 256.0f); row = (ch >> 4) * 0.0625f + (0.5f / 256.0f); @@ -629,9 +629,9 @@ static void pfnDrawCharacter( int ix, int iy, int iwidth, int iheight, int ch, i if( gameui.ds.scissor_test && !PIC_Scissor( &x, &y, &width, &height, &s1, &t1, &s2, &t2 )) return; - GL_SetRenderMode( kRenderTransTexture ); - R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, hFont ); - pglColor4ub( 255, 255, 255, 255 ); + ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture ); + ref.dllFuncs.R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, hFont ); + ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); } /* @@ -702,8 +702,8 @@ for drawing playermodel previews */ static void pfnClearScene( void ) { - R_PushScene(); - R_ClearScene(); + ref.dllFuncs.R_PushScene(); + ref.dllFuncs.R_ClearScene(); } /* @@ -726,10 +726,10 @@ static void pfnRenderScene( const ref_viewpass_t *rvp ) // don't allow special modes from menu copy.flags = 0; - R_Set2DMode( false ); - R_RenderFrame( © ); - R_Set2DMode( true ); - R_PopScene(); + ref.dllFuncs.R_Set2DMode( false ); + ref.dllFuncs.GL_RenderFrame( © ); + ref.dllFuncs.R_Set2DMode( true ); + ref.dllFuncs.R_PopScene(); } /* @@ -741,7 +741,7 @@ adding player model into visible list */ static int pfnAddEntity( int entityType, cl_entity_t *ent ) { - if( !R_AddEntity( ent, entityType )) + if( !ref.dllFuncs.R_AddEntity( ent, entityType )) return false; return true; } @@ -946,6 +946,11 @@ static void pfnStartBackgroundTrack( const char *introTrack, const char *mainTra S_StartBackgroundTrack( introTrack, mainTrack, 0, false ); } +static void GL_ProcessTexture( int texnum, float gamma, int topColor, int bottomColor ) +{ + ref.dllFuncs.GL_ProcessTexture( texnum, gamma, topColor, bottomColor ); +} + // engine callbacks static ui_enginefuncs_t gEngfuncs = { diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index d869ddae..590de8b8 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -17,11 +17,11 @@ GNU General Public License for more details. #include "client.h" #include "net_encode.h" #include "cl_tent.h" -#include "gl_local.h" #include "input.h" #include "kbutton.h" #include "vgui_draw.h" #include "library.h" +#include "vid_common.h" #define MAX_TOTAL_CMDS 32 #define MAX_CMD_BUFFER 8000 @@ -293,6 +293,7 @@ static float CL_LerpPoint( void ) frac = ( cl.time - cl.mtime[1] ) / f; } #endif + refState.time = cl.time; return frac; } @@ -1823,7 +1824,7 @@ void CL_SetupOverviewParams( void ) // calculate nearest aspect mapAspect = world.size[!ov->rotated] / world.size[ov->rotated]; - screenAspect = (float)glState.width / (float)glState.height; + screenAspect = (float)refState.width / (float)refState.height; aspect = Q_max( mapAspect, screenAspect ); ov->zNear = world.maxs[2]; @@ -2867,6 +2868,8 @@ void CL_AdjustClock( void ) if( cl.oldtime > cl.time ) cl.oldtime = cl.time; } + refState.oldtime = cl.oldtime; + refState.time = cl.time; } /* @@ -2971,13 +2974,13 @@ void CL_Init( void ) CL_InitLocal(); - R_Init(); // init renderer + VID_Init(); // init video S_Init(); // init sound // unreliable buffer. unsed for unreliable commands and voice stream MSG_Init( &cls.datagram, "cls.datagram", cls.datagram_buf, sizeof( cls.datagram_buf )); - IN_TouchInit(); + // IN_TouchInit(); Con_LoadHistory(); if( !CL_LoadProgs( va( "%s/%s", GI->dll_path, SI.clientlib))) @@ -3009,7 +3012,7 @@ void CL_Shutdown( void ) Host_WriteVideoConfig (); } - IN_TouchShutdown (); + // IN_TouchShutdown (); Joy_Shutdown (); CL_CloseDemoHeader (); IN_Shutdown (); diff --git a/engine/client/cl_mobile.c b/engine/client/cl_mobile.c index af11a7aa..d3480c97 100644 --- a/engine/client/cl_mobile.c +++ b/engine/client/cl_mobile.c @@ -19,7 +19,6 @@ GNU General Public License for more details. #include "client.h" #include "mobility_int.h" #include "library.h" -#include "gl_local.h" #include "input.h" #include "platform/platform.h" @@ -96,17 +95,22 @@ static void *pfnGetNativeObject( const char *obj ) return Platform_GetNativeObject( obj ); } +void IN_TouchHideButtons( const char *str, qboolean hide ) +{ + +} + static mobile_engfuncs_t gpMobileEngfuncs = { MOBILITY_API_VERSION, pfnVibrate, pfnEnableTextInput, - IN_TouchAddClientButton, - IN_TouchAddDefaultButton, - (void*)IN_TouchHideButtons, - IN_TouchRemoveButton, - (void*)IN_TouchSetClientOnly, - IN_TouchResetDefaultButtons, + NULL, // IN_TouchAddClientButton, + NULL, // IN_TouchAddDefaultButton, + IN_TouchHideButtons, + NULL, // IN_TouchRemoveButton, + NULL, // (void*)IN_TouchSetClientOnly, + NULL, // IN_TouchResetDefaultButtons, pfnDrawScaledCharacter, Sys_Warn, pfnGetNativeObject, diff --git a/engine/client/cl_netgraph.c b/engine/client/cl_netgraph.c index 9f6b5734..fddcf82b 100644 --- a/engine/client/cl_netgraph.c +++ b/engine/client/cl_netgraph.c @@ -15,7 +15,6 @@ GNU General Public License for more details. #include "common.h" #include "client.h" -#include "gl_local.h" #define NET_TIMINGS 1024 #define NET_TIMINGS_MASK (NET_TIMINGS - 1) @@ -75,12 +74,12 @@ NetGraph_FillRGBA shortcut */ static void NetGraph_DrawRect( wrect_t *rect, byte colors[4] ) { - pglColor4ubv( colors ); // color for this quad + ref.dllFuncs.Color4ub( colors[0], colors[1], colors[2], colors[3] ); // color for this quad - pglVertex2f( rect->left, rect->top ); - pglVertex2f( rect->left + rect->right, rect->top ); - pglVertex2f( rect->left + rect->right, rect->top + rect->bottom ); - pglVertex2f( rect->left, rect->top + rect->bottom ); + ref.dllFuncs.Vertex3f( rect->left, rect->top, 0 ); + ref.dllFuncs.Vertex3f( rect->left + rect->right, rect->top, 0 ); + ref.dllFuncs.Vertex3f( rect->left + rect->right, rect->top + rect->bottom, 0 ); + ref.dllFuncs.Vertex3f( rect->left, rect->top + rect->bottom, 0 ); } /* @@ -595,8 +594,8 @@ NetGraph_GetScreenPos void NetGraph_GetScreenPos( wrect_t *rect, int *w, int *x, int *y ) { rect->left = rect->top = 0; - rect->right = glState.width; - rect->bottom = glState.height; + rect->right = refState.width; + rect->bottom = refState.height; *w = Q_min( NET_TIMINGS, net_graphwidth->value ); if( rect->right < *w + 10 ) @@ -652,20 +651,17 @@ void SCR_DrawNetGraph( void ) if( net_graph->value < 3 ) { - pglEnable( GL_BLEND ); - pglDisable( GL_TEXTURE_2D ); - pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - pglBlendFunc( GL_SRC_ALPHA, GL_ONE ); - pglBegin( GL_QUADS ); // draw all the fills as a long solid sequence of quads for speedup reasons + ref.dllFuncs.GL_SetRenderMode( kRenderTransAdd ); + + ref.dllFuncs.Begin( TRI_QUADS ); // draw all the fills as a long solid sequence of quads for speedup reasons // NOTE: fill colors without texture at this point NetGraph_DrawDataUsage( x, y, w ); NetGraph_DrawTimes( rect, x, w ); - pglEnd(); - pglColor4ub( 255, 255, 255, 255 ); - pglEnable( GL_TEXTURE_2D ); - pglDisable( GL_BLEND ); + ref.dllFuncs.End(); + ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); + ref.dllFuncs.GL_SetRenderMode( kRenderNormal ); } } @@ -680,4 +676,4 @@ void CL_InitNetgraph( void ) packet_loss = packet_choke = 0.0; NetGraph_InitColors(); -} \ No newline at end of file +} diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index ac6321c3..5673cb8c 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -17,7 +17,6 @@ GNU General Public License for more details. #include "client.h" #include "net_encode.h" #include "particledef.h" -#include "gl_local.h" #include "cl_tent.h" #include "shake.h" #include "hltv.h" @@ -209,6 +208,9 @@ void CL_ParseServerTime( sizebuf_t *msg ) if( cl.oldtime > cl.time ) cl.oldtime = cl.time; + + refState.oldtime = cl.oldtime; + refState.time = cl.time; } /* @@ -250,7 +252,7 @@ void CL_ParseMovevars( sizebuf_t *msg ) // update sky if changed if( Q_strcmp( clgame.oldmovevars.skyName, clgame.movevars.skyName ) && cl.video_prepped ) - R_SetupSky( clgame.movevars.skyName ); + ref.dllFuncs.R_SetupSky( clgame.movevars.skyName ); memcpy( &clgame.oldmovevars, &clgame.movevars, sizeof( movevars_t )); clgame.entities->curstate.scale = clgame.movevars.waveHeight; @@ -658,7 +660,7 @@ void CL_RemoveCustomization( int nPlayerNum, customization_t *pRemove ) if( pList->resource.type == t_decal ) { if( cls.state == ca_active ) - R_DecalRemoveAll( pList->nUserData1 ); + ref.dllFuncs.R_DecalRemoveAll( pList->nUserData1 ); FS_FreeImage( pList->pInfo ); } } @@ -960,8 +962,8 @@ void CL_ParseServerData( sizebuf_t *msg ) // get splash name if( cls.demoplayback && ( cls.demonum != -1 )) - Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", cls.demoname, glState.wideScreen ? "16x9" : "4x3" )); - else Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, glState.wideScreen ? "16x9" : "4x3" )); + Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", cls.demoname, refState.wideScreen ? "16x9" : "4x3" )); + else Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, refState.wideScreen ? "16x9" : "4x3" )); Cvar_SetValue( "scr_loading", 0.0f ); // reset progress bar if(( cl_allow_levelshots->value && !cls.changelevel ) || cl.background ) @@ -1021,8 +1023,8 @@ void CL_ParseClientData( sizebuf_t *msg ) } } - cl.parsecount = i; // ack'd incoming messages. - cl.parsecountmod = cl.parsecount & CL_UPDATE_MASK; // index into window. + cl.parsecount = i; // ack'd incoming messages. + cl.parsecountmod = cl.parsecount & CL_UPDATE_MASK; // index into window. frame = &cl.frames[cl.parsecountmod]; // frame at index. frame->time = cl.mtime[0]; // mark network received time @@ -1548,18 +1550,15 @@ void CL_RegisterResources( sizebuf_t *msg ) CL_ClearWorld (); // tell rendering system we have a new set of models. - R_NewMap (); + ref.dllFuncs.R_NewMap (); CL_SetupOverviewParams(); - if( clgame.drawFuncs.R_NewMap != NULL ) - clgame.drawFuncs.R_NewMap(); - // release unused SpriteTextures for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ ) { if( mod->needload == NL_UNREFERENCED && COM_CheckString( mod->name )) - Mod_UnloadSpriteModel( mod ); + Mod_FreeModel( mod ); } Mod_FreeUnused (); @@ -2466,8 +2465,8 @@ void CL_ParseLegacyServerData( sizebuf_t *msg ) // get splash name if( cls.demoplayback && ( cls.demonum != -1 )) - Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", cls.demoname, glState.wideScreen ? "16x9" : "4x3" )); - else Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, glState.wideScreen ? "16x9" : "4x3" )); + Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", cls.demoname, refState.wideScreen ? "16x9" : "4x3" )); + else Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, refState.wideScreen ? "16x9" : "4x3" )); Cvar_SetValue( "scr_loading", 0.0f ); // reset progress bar if(( cl_allow_levelshots->value && !cls.changelevel ) || cl.background ) @@ -3132,18 +3131,15 @@ void CL_LegacyPrecache_f( void ) clgame.entities->model = cl.worldmodel; // tell rendering system we have a new set of models. - R_NewMap (); + ref.dllFuncs.R_NewMap (); CL_SetupOverviewParams(); - if( clgame.drawFuncs.R_NewMap != NULL ) - clgame.drawFuncs.R_NewMap(); - // release unused SpriteTextures for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ ) { if( mod->needload == NL_UNREFERENCED && COM_CheckString( mod->name )) - Mod_UnloadSpriteModel( mod ); + Mod_FreeModel( mod ); } // Mod_FreeUnused (); diff --git a/engine/client/cl_pmove.c b/engine/client/cl_pmove.c index 3e6e27b9..d82af9dc 100644 --- a/engine/client/cl_pmove.c +++ b/engine/client/cl_pmove.c @@ -816,7 +816,7 @@ static pmtrace_t pfnPlayerTrace( float *start, float *end, int traceFlags, int i return PM_PlayerTraceExt( clgame.pmove, start, end, traceFlags, clgame.pmove->numphysent, clgame.pmove->physents, ignore_pe, NULL ); } -static pmtrace_t *pfnTraceLine( float *start, float *end, int flags, int usehull, int ignore_pe ) +pmtrace_t *PM_TraceLine( float *start, float *end, int flags, int usehull, int ignore_pe ) { static pmtrace_t tr; int old_usehull; @@ -948,17 +948,6 @@ static pmtrace_t *pfnTraceLineEx( float *start, float *end, int flags, int usehu return &tr; } -static struct msurface_s *pfnTraceSurface( int ground, float *vstart, float *vend ) -{ - physent_t *pe; - - if( ground < 0 || ground >= clgame.pmove->numphysent ) - return NULL; // bad ground - - pe = &clgame.pmove->physents[ground]; - return PM_TraceSurface( pe, vstart, vend ); -} - /* =============== CL_InitClientMove @@ -989,7 +978,7 @@ void CL_InitClientMove( void ) // common utilities clgame.pmove->PM_Info_ValueForKey = Info_ValueForKey; - clgame.pmove->PM_Particle = CL_Particle; + clgame.pmove->PM_Particle = CL_Particle; // ref should be initialized here already clgame.pmove->PM_TestPlayerPosition = pfnTestPlayerPosition; clgame.pmove->Con_NPrintf = Con_NPrintf; clgame.pmove->Con_DPrintf = Con_DPrintf; @@ -1000,7 +989,7 @@ void CL_InitClientMove( void ) clgame.pmove->PM_TruePointContents = pfnTruePointContents; clgame.pmove->PM_HullPointContents = pfnHullPointContents; clgame.pmove->PM_PlayerTrace = pfnPlayerTrace; - clgame.pmove->PM_TraceLine = pfnTraceLine; + clgame.pmove->PM_TraceLine = PM_TraceLine; clgame.pmove->RandomLong = COM_RandomLong; clgame.pmove->RandomFloat = COM_RandomFloat; clgame.pmove->PM_GetModelType = pfnGetModelType; diff --git a/engine/client/cl_qparse.c b/engine/client/cl_qparse.c index 270d709e..32331c65 100644 --- a/engine/client/cl_qparse.c +++ b/engine/client/cl_qparse.c @@ -17,7 +17,6 @@ GNU General Public License for more details. #include "client.h" #include "net_encode.h" #include "particledef.h" -#include "gl_local.h" #include "cl_tent.h" #include "shake.h" #include "hltv.h" @@ -303,8 +302,8 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg ) // get splash name if( cls.demoplayback && ( cls.demonum != -1 )) - Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", cls.demoname, glState.wideScreen ? "16x9" : "4x3" )); - else Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, glState.wideScreen ? "16x9" : "4x3" )); + Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", cls.demoname, refState.wideScreen ? "16x9" : "4x3" )); + else Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, refState.wideScreen ? "16x9" : "4x3" )); Cvar_SetValue( "scr_loading", 0.0f ); // reset progress bar if(( cl_allow_levelshots->value && !cls.changelevel ) || cl.background ) @@ -350,8 +349,8 @@ static void CL_ParseQuakeClientData( sizebuf_t *msg ) // this is the frame update that this message corresponds to i = cls.netchan.incoming_sequence; - cl.parsecount = i; // ack'd incoming messages. - cl.parsecountmod = cl.parsecount & CL_UPDATE_MASK; // index into window. + cl.parsecount = i; // ack'd incoming messages. + cl.parsecountmod = cl.parsecount & CL_UPDATE_MASK; // index into window. frame = &cl.frames[cl.parsecountmod]; // frame at index. frame->time = cl.mtime[0]; // mark network received time frame->receivedtime = host.realtime; // time now that we are parsing. diff --git a/engine/client/cl_remap.c b/engine/client/cl_remap.c index 637dc4ed..c2d3406a 100644 --- a/engine/client/cl_remap.c +++ b/engine/client/cl_remap.c @@ -15,7 +15,6 @@ GNU General Public License for more details. #include "common.h" #include "client.h" -#include "gl_local.h" #include "studio.h" /* @@ -101,7 +100,7 @@ Dupliacte texture with remap pixels */ void CL_DuplicateTexture( mstudiotexture_t *ptexture, int topcolor, int bottomcolor ) { - gl_texture_t *glt; + const char *name; texture_t *tx = NULL; char texname[128]; int i, index; @@ -111,13 +110,13 @@ void CL_DuplicateTexture( mstudiotexture_t *ptexture, int topcolor, int bottomco // save off the real texture index index = ptexture->index; - glt = R_GetTexture( index ); - Q_snprintf( texname, sizeof( texname ), "#%i_%s", RI.currententity->curstate.number, glt->name + 1 ); + name = ref.dllFuncs.GL_TextureName( index ); + Q_snprintf( texname, sizeof( texname ), "#%i_%s", refState.currententity->curstate.number, name + 1 ); // search for pixels - for( i = 0; i < RI.currentmodel->numtextures; i++ ) + for( i = 0; i < refState.currentmodel->numtextures; i++ ) { - tx = RI.currentmodel->textures[i]; + tx = refState.currentmodel->textures[i]; if( tx->gl_texturenum == index ) break; // found } @@ -129,7 +128,7 @@ void CL_DuplicateTexture( mstudiotexture_t *ptexture, int topcolor, int bottomco memcpy( paletteBackup, pal, 768 ); raw = CL_CreateRawTextureFromPixels( tx, &size, topcolor, bottomcolor ); - ptexture->index = GL_LoadTexture( texname, raw, size, TF_FORCE_COLOR ); // do copy + ptexture->index = ref.dllFuncs.GL_LoadTexture( texname, raw, size, TF_FORCE_COLOR ); // do copy // restore original palette memcpy( pal, paletteBackup, 768 ); @@ -144,31 +143,31 @@ Update texture top and bottom colors */ void CL_UpdateStudioTexture( mstudiotexture_t *ptexture, int topcolor, int bottomcolor ) { - gl_texture_t *glt; rgbdata_t *pic; texture_t *tx = NULL; char texname[128], name[128], mdlname[128]; + const char *origtexname; int i, index; size_t size; byte paletteBackup[768]; byte *raw, *pal; // save off the real texture index - glt = R_GetTexture( ptexture->index ); + origtexname = ref.dllFuncs.GL_TextureName( ptexture->index ); // build name of original texture - Q_strncpy( mdlname, RI.currentmodel->name, sizeof( mdlname )); + Q_strncpy( mdlname, refState.currentmodel->name, sizeof( mdlname )); COM_FileBase( ptexture->name, name ); COM_StripExtension( mdlname ); Q_snprintf( texname, sizeof( texname ), "#%s/%s.mdl", mdlname, name ); - index = GL_FindTexture( texname ); + index = ref.dllFuncs.GL_FindTexture( texname ); if( !index ) return; // couldn't find texture // search for pixels - for( i = 0; i < RI.currentmodel->numtextures; i++ ) + for( i = 0; i < refState.currentmodel->numtextures; i++ ) { - tx = RI.currentmodel->textures[i]; + tx = refState.currentmodel->textures[i]; if( tx->gl_texturenum == index ) break; // found } @@ -180,14 +179,14 @@ void CL_UpdateStudioTexture( mstudiotexture_t *ptexture, int topcolor, int botto memcpy( paletteBackup, pal, 768 ); raw = CL_CreateRawTextureFromPixels( tx, &size, topcolor, bottomcolor ); - pic = FS_LoadImage( glt->name, raw, size ); + pic = FS_LoadImage( origtexname, raw, size ); if( !pic ) { - Con_DPrintf( S_ERROR "Couldn't update texture %s\n", glt->name ); + Con_DPrintf( S_ERROR "Couldn't update texture %s\n", origtexname ); return; } - index = GL_UpdateTextureInternal( glt->name, pic, 0 ); + index = GL_UpdateTextureInternal( origtexname, pic, 0 ); FS_FreeImage( pic ); // restore original palette @@ -209,15 +208,15 @@ void CL_UpdateAliasTexture( unsigned short *texture, int skinnum, int topcolor, rgbdata_t skin, *pic; texture_t *tx; - if( !texture || !RI.currentmodel->textures ) + if( !texture || !refState.currentmodel->textures ) return; // no remapinfo in model - tx = RI.currentmodel->textures[skinnum]; + tx = refState.currentmodel->textures[skinnum]; if( !tx ) return; // missing texture ? if( *texture == 0 ) { - Q_snprintf( texname, sizeof( texname ), "%s:remap%i_%i", RI.currentmodel->name, skinnum, RI.currententity->index ); + Q_snprintf( texname, sizeof( texname ), "%s:remap%i_%i", refState.currentmodel->name, skinnum, refState.currententity->index ); skin.width = tx->width; skin.height = tx->height; skin.depth = skin.numMips = 1; @@ -232,7 +231,7 @@ void CL_UpdateAliasTexture( unsigned short *texture, int skinnum, int topcolor, } // and now we can remap with internal routines - GL_ProcessTexture( *texture, -1.0f, topcolor, bottomcolor ); + ref.dllFuncs.GL_ProcessTexture( *texture, -1.0f, topcolor, bottomcolor ); } /* @@ -251,10 +250,10 @@ void CL_AllocRemapInfo( int topcolor, int bottomcolor ) mstudiotexture_t *src, *dst; int i, size; - if( !RI.currententity ) return; - i = ( RI.currententity == &clgame.viewent ) ? clgame.maxEntities : RI.currententity->curstate.number; + if( !refState.currententity ) return; + i = ( refState.currententity == &clgame.viewent ) ? clgame.maxEntities : refState.currententity->curstate.number; - if( !RI.currentmodel || ( RI.currentmodel->type != mod_alias && RI.currentmodel->type != mod_studio )) + if( !refState.currentmodel || ( refState.currentmodel->type != mod_alias && refState.currentmodel->type != mod_studio )) { // entity has changed model by another type, release remap info if( clgame.remap_info[i] ) @@ -266,7 +265,7 @@ void CL_AllocRemapInfo( int topcolor, int bottomcolor ) } // model doesn't contains remap textures - if( RI.currentmodel->numtextures <= 0 ) + if( refState.currentmodel->numtextures <= 0 ) { // entity has changed model with no remap textures if( clgame.remap_info[i] ) @@ -277,16 +276,16 @@ void CL_AllocRemapInfo( int topcolor, int bottomcolor ) return; } - if( RI.currentmodel->type == mod_studio ) + if( refState.currentmodel->type == mod_studio ) { - phdr = (studiohdr_t *)Mod_StudioExtradata( RI.currentmodel ); + phdr = (studiohdr_t *)Mod_StudioExtradata( refState.currentmodel ); if( !phdr ) return; // bad model? src = (mstudiotexture_t *)(((byte *)phdr) + phdr->textureindex); dst = (clgame.remap_info[i] ? clgame.remap_info[i]->ptexture : NULL); // NOTE: we must copy all the structures 'mstudiotexture_t' for easy access when model is rendering - if( !CL_CmpStudioTextures( phdr->numtextures, src, dst ) || clgame.remap_info[i]->model != RI.currentmodel ) + if( !CL_CmpStudioTextures( phdr->numtextures, src, dst ) || clgame.remap_info[i]->model != refState.currentmodel ) { // this code catches studiomodel change with another studiomodel with remap textures // e.g. playermodel 'barney' with playermodel 'gordon' @@ -318,13 +317,13 @@ void CL_AllocRemapInfo( int topcolor, int bottomcolor ) CL_DuplicateTexture( &dst[i], topcolor, bottomcolor ); } } - else if( RI.currentmodel->type == mod_alias ) + else if( refState.currentmodel->type == mod_alias ) { - ahdr = (aliashdr_t *)Mod_AliasExtradata( RI.currentmodel ); + ahdr = (aliashdr_t *)Mod_AliasExtradata( refState.currentmodel ); if( !ahdr ) return; // bad model? // NOTE: we must copy all the structures 'mstudiotexture_t' for easy access when model is rendering - if( !clgame.remap_info[i] || clgame.remap_info[i]->model != RI.currentmodel ) + if( !clgame.remap_info[i] || clgame.remap_info[i]->model != refState.currentmodel ) { // this code catches studiomodel change with another studiomodel with remap textures // e.g. playermodel 'barney' with playermodel 'gordon' @@ -337,7 +336,7 @@ void CL_AllocRemapInfo( int topcolor, int bottomcolor ) return; } - info->numtextures = RI.currentmodel->numtextures; + info->numtextures = refState.currentmodel->numtextures; // alias remapping is easy CL_UpdateRemapInfo( topcolor, bottomcolor ); @@ -348,7 +347,7 @@ void CL_AllocRemapInfo( int topcolor, int bottomcolor ) return; } - info->model = RI.currentmodel; + info->model = refState.currentmodel; } /* @@ -363,7 +362,7 @@ void CL_UpdateRemapInfo( int topcolor, int bottomcolor ) remap_info_t *info; int i; - i = ( RI.currententity == &clgame.viewent ) ? clgame.maxEntities : RI.currententity->curstate.number; + i = ( refState.currententity == &clgame.viewent ) ? clgame.maxEntities : refState.currententity->curstate.number; info = clgame.remap_info[i]; if( !info ) return; // no remap info @@ -403,11 +402,11 @@ void CL_FreeRemapInfo( remap_info_t *info ) if( info->ptexture != NULL ) { if( FBitSet( info->ptexture[i].flags, STUDIO_NF_COLORMAP )) - GL_FreeTexture( info->ptexture[i].index ); + ref.dllFuncs.GL_FreeTexture( info->ptexture[i].index ); } if( info->textures[i] != 0 ) - GL_FreeTexture( info->textures[i] ); + ref.dllFuncs.GL_FreeTexture( info->textures[i] ); } Mem_Free( info ); // release struct diff --git a/engine/client/cl_render.c b/engine/client/cl_render.c new file mode 100644 index 00000000..a1a4ac81 --- /dev/null +++ b/engine/client/cl_render.c @@ -0,0 +1,345 @@ +/* +cl_render.c - RenderAPI loader & implementation +Copyright (C) 2019 a1batross + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + +#ifndef XASH_DEDICATED + +#include "common.h" +#include "client.h" +#include "library.h" +#include "platform/platform.h" + +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 ); +} + +lightstyle_t *CL_GetLightStyle( int number ) +{ + Assert( number >= 0 && number < MAX_LIGHTSTYLES ); + return &cl.lightstyles[number]; +} + +const ref_overview_t *GL_GetOverviewParms( void ) +{ + return &clgame.overView; +} + +static void *R_Mem_Alloc( size_t cb, const char *filename, const int fileline ) +{ + return _Mem_Alloc( cls.mempool, cb, true, filename, fileline ); +} + +static void R_Mem_Free( void *mem, const char *filename, const int fileline ) +{ + if( !mem ) return; + _Mem_Free( mem, filename, fileline ); +} + +/* +========= +pfnGetFilesList + +========= +*/ +static char **pfnGetFilesList( const char *pattern, int *numFiles, int gamedironly ) +{ + static search_t *t = NULL; + + if( t ) Mem_Free( t ); // release prev search + + t = FS_Search( pattern, true, gamedironly ); + + if( !t ) + { + if( numFiles ) *numFiles = 0; + return NULL; + } + + if( numFiles ) *numFiles = t->numfilenames; + return t->filenames; +} + +static uint pfnFileBufferCRC32( const void *buffer, const int length ) +{ + uint modelCRC = 0; + + if( !buffer || length <= 0 ) + return modelCRC; + + CRC32_Init( &modelCRC ); + CRC32_ProcessBuffer( &modelCRC, buffer, length ); + return CRC32_Final( modelCRC ); +} + +/* +================= +R_EnvShot + +================= +*/ +static void R_EnvShot( const float *vieworg, const char *name, qboolean skyshot, int shotsize ) +{ + static vec3_t viewPoint; + + if( !COM_CheckString( name )) + return; + + if( cls.scrshot_action != scrshot_inactive ) + { + if( cls.scrshot_action != scrshot_skyshot && cls.scrshot_action != scrshot_envshot ) + Con_Printf( S_ERROR "R_%sShot: subsystem is busy, try for next frame.\n", skyshot ? "Sky" : "Env" ); + return; + } + + cls.envshot_vieworg = NULL; // use client view + Q_strncpy( cls.shotname, name, sizeof( cls.shotname )); + + if( vieworg ) + { + // make sure what viewpoint don't temporare + VectorCopy( vieworg, viewPoint ); + cls.envshot_vieworg = viewPoint; + cls.envshot_disable_vis = true; + } + + // make request for envshot + if( skyshot ) cls.scrshot_action = scrshot_skyshot; + else cls.scrshot_action = scrshot_envshot; + + // catch negative values + cls.envshot_viewsize = max( 0, shotsize ); +} + +/* +============= +CL_GenericHandle + +============= +*/ +const char *CL_GenericHandle( int fileindex ) +{ + if( fileindex < 0 || fileindex >= MAX_CUSTOM ) + return 0; + return cl.files_precache[fileindex]; +} + +int CL_RenderGetParm( const int parm, const int arg, const qboolean checkRef ) +{ + switch( parm ) + { + case PARM_BSP2_SUPPORTED: +#ifdef SUPPORT_BSP2_FORMAT + return 1; +#endif + return 0; + case PARM_SKY_SPHERE: + return FBitSet( world.flags, FWORLD_SKYSPHERE ) && !FBitSet( world.flags, FWORLD_CUSTOM_SKYBOX ); + case PARAM_GAMEPAUSED: + return cl.paused; + case PARM_CLIENT_INGAME: + return CL_IsInGame(); + case PARM_MAX_ENTITIES: + return clgame.maxEntities; + case PARM_FEATURES: + return host.features; + case PARM_MAP_HAS_DELUXE: + return FBitSet( world.flags, FWORLD_HAS_DELUXEMAP ); + case PARM_CLIENT_ACTIVE: + return (cls.state == ca_active); + case PARM_DEDICATED_SERVER: + return (host.type == HOST_DEDICATED); + case PARM_WATER_ALPHA: + return FBitSet( world.flags, FWORLD_WATERALPHA ); + default: + // indicates call from client.dll + if( checkRef ) + { + return ref.dllFuncs.RefGetParm( parm, arg ); + } + // call issued from ref_dll, check extensions here + else switch( parm ) + { + case PARM_DEV_OVERVIEW: + return CL_IsDevOverviewMode(); + case PARM_THIRDPERSON: + return CL_IsThirdPerson(); + case PARM_QUAKE_COMPATIBLE: + return Host_IsQuakeCompatible(); + case PARM_PLAYER_INDEX: + return cl.playernum + 1; + case PARM_VIEWENT_INDEX: + return cl.viewentity; + case PARM_CONNSTATE: + return (int)cls.state; + case PARM_PLAYING_DEMO: + return cls.demoplayback; + case PARM_WATER_LEVEL: + return cl.local.waterlevel; + case PARM_MAX_CLIENTS: + return cl.maxclients; + case PARM_LOCAL_HEALTH: + return cl.local.health; + case PARM_LOCAL_GAME: + return Host_IsLocalGame(); + case PARM_NUMENTITIES: + return pfnNumberOfEntities(); + case PARM_NUMMODELS: + return cl.nummodels; + } + } + return 0; +} + +static int pfnRenderGetParm( int parm, int arg ) +{ + return CL_RenderGetParm( parm, arg, true ); +} + +static render_api_t gRenderAPI = +{ + pfnRenderGetParm, // GL_RenderGetParm, + NULL, // R_GetDetailScaleForTexture, + NULL, // R_GetExtraParmsForTexture, + CL_GetLightStyle, + CL_GetDynamicLight, + CL_GetEntityLight, + LightToTexGamma, + NULL, // R_GetFrameTime, + NULL, // R_SetCurrentEntity, + NULL, // R_SetCurrentModel, + R_FatPVS, + R_StoreEfrags, + NULL, // GL_FindTexture, + NULL, // GL_TextureName, + NULL, // GL_TextureData, + NULL, // GL_LoadTexture, + NULL, // GL_CreateTexture, + NULL, // GL_LoadTextureArray, + NULL, // GL_CreateTextureArray, + NULL, // GL_FreeTexture, + NULL, // DrawSingleDecal, + NULL, // R_DecalSetupVerts, + NULL, // R_EntityRemoveDecals, + (void*)AVI_LoadVideo, + (void*)AVI_GetVideoInfo, + (void*)AVI_GetVideoFrameNumber, + (void*)AVI_GetVideoFrame, + NULL, // R_UploadStretchRaw, + (void*)AVI_FreeVideo, + (void*)AVI_IsActive, + S_StreamAviSamples, + NULL, + NULL, + NULL, // GL_Bind, + NULL, // GL_SelectTexture, + NULL, // GL_LoadTexMatrixExt, + NULL, // GL_LoadIdentityTexMatrix, + NULL, // GL_CleanUpTextureUnits, + NULL, // GL_TexGen, + NULL, // GL_TextureTarget, + NULL, // GL_SetTexCoordArrayMode, + GL_GetProcAddress, + NULL, // GL_UpdateTexSize, + NULL, + NULL, + NULL, // CL_DrawParticlesExternal, + R_EnvShot, + pfnSPR_LoadExt, + NULL, // R_LightVec, + NULL, // R_StudioGetTexture, + GL_GetOverviewParms, + CL_GenericHandle, + NULL, + NULL, + R_Mem_Alloc, + R_Mem_Free, + pfnGetFilesList, + pfnFileBufferCRC32, + COM_CompareFileTime, + Host_Error, + (void*)CL_ModelHandle, + pfnTime, + Cvar_Set, + S_FadeMusicVolume, + COM_SetRandomSeed, +}; + +static void R_FillRenderAPIFromRef( render_api_t *to, const ref_interface_t *from ) +{ + to->GetDetailScaleForTexture = from->GetDetailScaleForTexture; + to->GetExtraParmsForTexture = from->GetExtraParmsForTexture; + to->GetFrameTime = from->GetFrameTime; + to->R_SetCurrentEntity = from->R_SetCurrentEntity; + to->R_SetCurrentModel = from->R_SetCurrentModel; + to->GL_FindTexture = from->GL_FindTexture; + to->GL_TextureName = from->GL_TextureName; + to->GL_TextureData = from->GL_TextureData; + to->GL_LoadTexture = from->GL_LoadTexture; + to->GL_CreateTexture = from->GL_CreateTexture; + to->GL_LoadTextureArray = from->GL_LoadTextureArray; + to->GL_CreateTextureArray = from->GL_CreateTextureArray; + to->GL_FreeTexture = from->GL_FreeTexture; + to->DrawSingleDecal = from->DrawSingleDecal; + to->R_DecalSetupVerts = from->R_DecalSetupVerts; + to->R_EntityRemoveDecals = from->R_EntityRemoveDecals; + to->AVI_UploadRawFrame = from->AVI_UploadRawFrame; + to->GL_Bind = from->GL_Bind; + to->GL_SelectTexture = from->GL_SelectTexture; + to->GL_LoadTextureMatrix = from->GL_LoadTextureMatrix; + to->GL_TexMatrixIdentity = from->GL_TexMatrixIdentity; + to->GL_CleanUpTextureUnits = from->GL_CleanUpTextureUnits; + to->GL_TexGen = from->GL_TexGen; + to->GL_TextureTarget = from->GL_TextureTarget; + to->GL_TexCoordArrayMode = from->GL_TexCoordArrayMode; + to->GL_UpdateTexSize = from->GL_UpdateTexSize; + to->GL_DrawParticles = from->GL_DrawParticles; + to->LightVec = from->LightVec; + to->StudioGetTexture = from->StudioGetTexture; +} + +/* +=============== +R_InitRenderAPI + +Initialize client external rendering +=============== +*/ +qboolean R_InitRenderAPI( void ) +{ + // make sure what render functions is cleared + memset( &clgame.drawFuncs, 0, sizeof( clgame.drawFuncs )); + + // fill missing functions from renderer + R_FillRenderAPIFromRef( &gRenderAPI, &ref.dllFuncs ); + + if( clgame.dllFuncs.pfnGetRenderInterface ) + { + if( clgame.dllFuncs.pfnGetRenderInterface( CL_RENDER_INTERFACE_VERSION, &gRenderAPI, &clgame.drawFuncs )) + { + Con_Reportf( "CL_LoadProgs: ^2initailized extended RenderAPI ^7ver. %i\n", CL_RENDER_INTERFACE_VERSION ); + return true; + } + + // make sure what render functions is cleared + memset( &clgame.drawFuncs, 0, sizeof( clgame.drawFuncs )); + + return false; // just tell user about problems + } + + // render interface is missed + return true; +} + +#endif // XASH_DEDICATED diff --git a/engine/client/cl_scrn.c b/engine/client/cl_scrn.c index 65f590b3..405bbdf2 100644 --- a/engine/client/cl_scrn.c +++ b/engine/client/cl_scrn.c @@ -15,7 +15,6 @@ GNU General Public License for more details. #include "common.h" #include "client.h" -#include "gl_local.h" #include "vgui_draw.h" #include "qfont.h" #include "input.h" @@ -99,7 +98,7 @@ void SCR_DrawFPS( int height ) } Con_DrawStringLen( fpsstring, &offset, NULL ); - Con_DrawString( glState.width - offset - 4, height, fpsstring, color ); + Con_DrawString( refState.width - offset - 4, height, fpsstring, color ); } /* @@ -148,7 +147,7 @@ void SCR_NetSpeeds( void ) Q_snprintf( msg, sizeof( msg ), "sv fps: ^1%4i min, ^3%4i cur, ^2%4i max\ncl fps: ^1%4i min, ^3%4i cur, ^2%4i max\nGame Time: %02d:%02d\nTotal received from server: %s\nTotal sent to server: %s\n", min_svfps, cur_svfps, max_svfps, min_clfps, cur_clfps, max_clfps, (int)(time / 60.0f ), (int)fmod( time, 60.0f ), Q_memprint( cls.netchan.total_received ), Q_memprint( cls.netchan.total_sended )); - x = glState.width - 320; + x = refState.width - 320; y = 384; Con_DrawStringLen( NULL, NULL, &height ); @@ -181,13 +180,13 @@ void SCR_RSpeeds( void ) if( !host.allow_console ) return; - if( R_SpeedsMessage( msg, sizeof( msg ))) + if( ref.dllFuncs.R_SpeedsMessage( msg, sizeof( msg ))) { int x, y, height; char *p, *start, *end; rgba_t color; - x = glState.width - 340; + x = refState.width - 340; y = 64; Con_DrawStringLen( NULL, NULL, &height ); @@ -227,6 +226,37 @@ void SCR_MakeLevelShot( void ) Cbuf_AddText( "levelshot\n" ); } +/* +=============== +VID_WriteOverviewScript + +Create overview script file +=============== +*/ +void VID_WriteOverviewScript( void ) +{ + ref_overview_t *ov = &clgame.overView; + string filename; + file_t *f; + + Q_snprintf( filename, sizeof( filename ), "overviews/%s.txt", clgame.mapname ); + + f = FS_Open( filename, "w", false ); + if( !f ) return; + + FS_Printf( f, "// overview description file for %s.bsp\n\n", clgame.mapname ); + FS_Print( f, "global\n{\n" ); + FS_Printf( f, "\tZOOM\t%.2f\n", ov->flZoom ); + FS_Printf( f, "\tORIGIN\t%.2f\t%.2f\t%.2f\n", ov->origin[0], ov->origin[1], ov->origin[2] ); + FS_Printf( f, "\tROTATED\t%i\n", ov->rotated ? 1 : 0 ); + FS_Print( f, "}\n\nlayer\n{\n" ); + FS_Printf( f, "\tIMAGE\t\"overviews/%s.bmp\"\n", clgame.mapname ); + FS_Printf( f, "\tHEIGHT\t%.2f\n", ov->zFar ); // ??? + FS_Print( f, "}\n" ); + + FS_Close( f ); +} + /* ================ SCR_MakeScreenShot @@ -246,25 +276,27 @@ void SCR_MakeScreenShot( void ) switch( cls.scrshot_action ) { case scrshot_normal: - iRet = VID_ScreenShot( cls.shotname, VID_SCREENSHOT ); + iRet = ref.dllFuncs.VID_ScreenShot( cls.shotname, VID_SCREENSHOT ); break; case scrshot_snapshot: - iRet = VID_ScreenShot( cls.shotname, VID_SNAPSHOT ); + iRet = ref.dllFuncs.VID_ScreenShot( cls.shotname, VID_SNAPSHOT ); break; case scrshot_plaque: - iRet = VID_ScreenShot( cls.shotname, VID_LEVELSHOT ); + iRet = ref.dllFuncs.VID_ScreenShot( cls.shotname, VID_LEVELSHOT ); break; case scrshot_savegame: - iRet = VID_ScreenShot( cls.shotname, VID_MINISHOT ); + iRet = ref.dllFuncs.VID_ScreenShot( cls.shotname, VID_MINISHOT ); break; case scrshot_envshot: - iRet = VID_CubemapShot( cls.shotname, viewsize, cls.envshot_vieworg, false ); + iRet = ref.dllFuncs.VID_CubemapShot( cls.shotname, viewsize, cls.envshot_vieworg, false ); break; case scrshot_skyshot: - iRet = VID_CubemapShot( cls.shotname, viewsize, cls.envshot_vieworg, true ); + iRet = ref.dllFuncs.VID_CubemapShot( cls.shotname, viewsize, cls.envshot_vieworg, true ); break; case scrshot_mapshot: - iRet = VID_ScreenShot( cls.shotname, VID_MAPSHOT ); + iRet = ref.dllFuncs.VID_ScreenShot( cls.shotname, VID_MAPSHOT ); + if( iRet ) + VID_WriteOverviewScript(); // store overview script too break; case scrshot_inactive: return; @@ -295,9 +327,9 @@ void SCR_DrawPlaque( void ) { if(( cl_allow_levelshots->value && !cls.changelevel ) || cl.background ) { - int levelshot = GL_LoadTexture( cl_levelshot_name->string, NULL, 0, TF_IMAGE ); - GL_SetRenderMode( kRenderNormal ); - R_DrawStretchPic( 0, 0, glState.width, glState.height, 0, 0, 1, 1, levelshot ); + int levelshot = ref.dllFuncs.GL_LoadTexture( cl_levelshot_name->string, NULL, 0, TF_IMAGE ); + ref.dllFuncs.GL_SetRenderMode( kRenderNormal ); + ref.dllFuncs.R_DrawStretchPic( 0, 0, refState.width, refState.height, 0, 0, 1, 1, levelshot ); if( !cl.background ) CL_DrawHUD( CL_LOADING ); } } @@ -367,7 +399,7 @@ SCR_DirtyScreen void SCR_DirtyScreen( void ) { SCR_AddDirtyPoint( 0, 0 ); - SCR_AddDirtyPoint( glState.width - 1, glState.height - 1 ); + SCR_AddDirtyPoint( refState.width - 1, refState.height - 1 ); } /* @@ -419,7 +451,7 @@ void SCR_TileClear( void ) { // clear above view screen i = clear.y2 < top-1 ? clear.y2 : top - 1; - R_DrawTileClear( clear.x1, clear.y1, clear.x2 - clear.x1 + 1, i - clear.y1 + 1 ); + ref.dllFuncs.R_DrawTileClear( cls.tileImage, clear.x1, clear.y1, clear.x2 - clear.x1 + 1, i - clear.y1 + 1 ); clear.y1 = top; } @@ -427,7 +459,7 @@ void SCR_TileClear( void ) { // clear below view screen i = clear.y1 > bottom + 1 ? clear.y1 : bottom + 1; - R_DrawTileClear( clear.x1, i, clear.x2 - clear.x1 + 1, clear.y2 - i + 1 ); + ref.dllFuncs.R_DrawTileClear( cls.tileImage, clear.x1, i, clear.x2 - clear.x1 + 1, clear.y2 - i + 1 ); clear.y2 = bottom; } @@ -435,7 +467,7 @@ void SCR_TileClear( void ) { // clear left of view screen i = clear.x2 < left - 1 ? clear.x2 : left - 1; - R_DrawTileClear( clear.x1, clear.y1, i - clear.x1 + 1, clear.y2 - clear.y1 + 1 ); + ref.dllFuncs.R_DrawTileClear( cls.tileImage, clear.x1, clear.y1, i - clear.x1 + 1, clear.y2 - clear.y1 + 1 ); clear.x1 = left; } @@ -443,7 +475,7 @@ void SCR_TileClear( void ) { // clear left of view screen i = clear.x1 > right + 1 ? clear.x1 : right + 1; - R_DrawTileClear( i, clear.y1, clear.x2 - i + 1, clear.y2 - clear.y1 + 1 ); + ref.dllFuncs.R_DrawTileClear( cls.tileImage, i, clear.y1, clear.x2 - i + 1, clear.y2 - clear.y1 + 1 ); clear.x2 = right; } } @@ -495,7 +527,7 @@ qboolean SCR_LoadFixedWidthFont( const char *fontname ) if( !FS_FileExists( fontname, false )) return false; - cls.creditsFont.hFontTexture = GL_LoadTexture( fontname, NULL, 0, TF_IMAGE|TF_KEEP_SOURCE ); + cls.creditsFont.hFontTexture = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, TF_IMAGE|TF_KEEP_SOURCE ); R_GetTextureParms( &fontWidth, NULL, cls.creditsFont.hFontTexture ); cls.creditsFont.charHeight = clgame.scrInfo.iCharHeight = fontWidth / 16; cls.creditsFont.type = FONT_FIXED; @@ -527,7 +559,7 @@ qboolean SCR_LoadVariableWidthFont( const char *fontname ) if( !FS_FileExists( fontname, false )) return false; - cls.creditsFont.hFontTexture = GL_LoadTexture( fontname, NULL, 0, TF_IMAGE ); + cls.creditsFont.hFontTexture = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, TF_IMAGE ); R_GetTextureParms( &fontWidth, NULL, cls.creditsFont.hFontTexture ); // half-life font with variable chars witdh @@ -636,24 +668,24 @@ void SCR_RegisterTextures( void ) // register gfx.wad images if( FS_FileExists( "gfx/paused.lmp", false )) - cls.pauseIcon = GL_LoadTexture( "gfx/paused.lmp", NULL, 0, TF_IMAGE ); + cls.pauseIcon = ref.dllFuncs.GL_LoadTexture( "gfx/paused.lmp", NULL, 0, TF_IMAGE ); else if( FS_FileExists( "gfx/pause.lmp", false )) - cls.pauseIcon = GL_LoadTexture( "gfx/pause.lmp", NULL, 0, TF_IMAGE ); + cls.pauseIcon = ref.dllFuncs.GL_LoadTexture( "gfx/pause.lmp", NULL, 0, TF_IMAGE ); if( FS_FileExists( "gfx/lambda.lmp", false )) { if( cl_allow_levelshots->value ) - cls.loadingBar = GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE ); - else cls.loadingBar = GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE ); + cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE ); + else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE ); } else if( FS_FileExists( "gfx/loading.lmp", false )) { if( cl_allow_levelshots->value ) - cls.loadingBar = GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE ); - else cls.loadingBar = GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE ); + cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE ); + else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE ); } - cls.tileImage = GL_LoadTexture( "gfx/backtile.lmp", NULL, 0, TF_NOMIPMAP ); + cls.tileImage = ref.dllFuncs.GL_LoadTexture( "gfx/backtile.lmp", NULL, 0, TF_NOMIPMAP ); } /* @@ -695,11 +727,11 @@ void SCR_VidInit( void ) // update screen sizes for menu if( gameui.globals ) { - gameui.globals->scrWidth = glState.width; - gameui.globals->scrHeight = glState.height; + gameui.globals->scrWidth = refState.width; + gameui.globals->scrHeight = refState.height; } - VGui_Startup( glState.width, glState.height ); + VGui_Startup( refState.width, refState.height ); CL_ClearSpriteTextures(); // now all hud sprites are invalid @@ -731,7 +763,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 53529be9..d86a9683 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -20,7 +20,6 @@ GNU General Public License for more details. #include "triangleapi.h" #include "cl_tent.h" #include "pm_local.h" -#include "gl_local.h" #include "studio.h" #include "wadfile.h" // acess decal size #include "sound.h" @@ -225,7 +224,7 @@ int CL_FxBlend( cl_entity_t *e ) blend = e->curstate.renderamt + 0x10 * sin( cl.time * 8 + offset ); break; case kRenderFxFadeSlow: - if( RP_NORMALPASS( )) + if( ref.dllFuncs.IsNormalPass( )) { if( e->curstate.renderamt > 0 ) e->curstate.renderamt -= 1; @@ -234,7 +233,7 @@ int CL_FxBlend( cl_entity_t *e ) blend = e->curstate.renderamt; break; case kRenderFxFadeFast: - if( RP_NORMALPASS( )) + if( ref.dllFuncs.IsNormalPass( )) { if( e->curstate.renderamt > 3 ) e->curstate.renderamt -= 4; @@ -243,7 +242,7 @@ int CL_FxBlend( cl_entity_t *e ) blend = e->curstate.renderamt; break; case kRenderFxSolidSlow: - if( RP_NORMALPASS( )) + if( ref.dllFuncs.IsNormalPass( )) { if( e->curstate.renderamt < 255 ) e->curstate.renderamt += 1; @@ -252,7 +251,7 @@ int CL_FxBlend( cl_entity_t *e ) blend = e->curstate.renderamt; break; case kRenderFxSolidFast: - if( RP_NORMALPASS( )) + if( ref.dllFuncs.IsNormalPass( )) { if( e->curstate.renderamt < 252 ) e->curstate.renderamt += 4; @@ -288,8 +287,8 @@ int CL_FxBlend( cl_entity_t *e ) case kRenderFxHologram: case kRenderFxDistort: VectorCopy( e->origin, tmp ); - VectorSubtract( tmp, RI.vieworg, tmp ); - dist = DotProduct( tmp, RI.vforward ); + VectorSubtract( tmp, refState.vieworg, tmp ); + dist = DotProduct( tmp, refState.vforward ); // turn off distance fade if( e->curstate.renderfx == kRenderFxDistort ) @@ -522,7 +521,7 @@ int CL_TempEntAddEntity( cl_entity_t *pEntity ) // add to list if( CL_AddVisibleEntity( pEntity, ET_TEMPENTITY )) - r_stats.c_active_tents_count++; + ref.dllFuncs.R_IncrementSpeedsCounter( RS_ACTIVE_TENTS ); return 1; } @@ -2013,6 +2012,8 @@ void R_Sprite_WallPuff( TEMPENTITY *pTemp, float scale ) pTemp->die = cl.time + 0.01f; } + + /* ============== CL_ParseTempEntity @@ -2721,6 +2722,18 @@ void CL_DecayLights( void ) } } +dlight_t *CL_GetDynamicLight( int number ) +{ + Assert( number >= 0 && number < MAX_DLIGHTS ); + return &cl_dlights[number]; +} + +dlight_t *CL_GetEntityLight( int number ) +{ + Assert( number >= 0 && number < MAX_ELIGHTS ); + return &cl_elights[number]; +} + /* ================ CL_UpdateFlashlight @@ -2958,8 +2971,8 @@ void CL_TestLights( void ) r = 64 * ((i % 4) - 1.5f ); f = 64 * ( i / 4) + 128; - for( j = 0; j < 3; j++ ) - dl->origin[j] = RI.vieworg[j] + RI.vforward[j] * f + RI.vright[j] * r; + VectorMAM( f, refState.vforward, r, refState.vright, dl->origin ); + VectorAdd( dl->origin, refState.vieworg, dl->origin ); dl->color.r = ((((i % 6) + 1) & 1)>>0) * 255; dl->color.g = ((((i % 6) + 1) & 2)>>1) * 255; @@ -2976,18 +2989,6 @@ DECAL MANAGEMENT ============================================================== */ -/* -=============== -CL_DecalShoot - -normal temporary decal -=============== -*/ -void CL_DecalShoot( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags ) -{ - R_DecalShoot( textureIndex, entityIndex, modelIndex, pos, flags, 1.0f ); -} - /* =============== CL_FireCustomDecal @@ -2997,7 +2998,19 @@ custom temporary decal */ void CL_FireCustomDecal( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags, float scale ) { - R_DecalShoot( textureIndex, entityIndex, modelIndex, pos, flags, scale ); + ref.dllFuncs.R_DecalShoot( textureIndex, entityIndex, modelIndex, pos, flags, scale ); +} + +/* +=============== +CL_DecalShoot + +normal temporary decal +=============== +*/ +void CL_DecalShoot( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags ) +{ + CL_FireCustomDecal( textureIndex, entityIndex, modelIndex, pos, flags, 1.0f ); } /* @@ -3028,7 +3041,7 @@ void CL_PlayerDecal( int playernum, int customIndex, int entityIndex, float *pos } } - R_DecalShoot( textureIndex, entityIndex, 0, pos, FDECAL_CUSTOM, 1.0f ); + CL_DecalShoot( textureIndex, entityIndex, 0, pos, FDECAL_CUSTOM ); } /* @@ -3068,7 +3081,7 @@ int CL_DecalIndex( int id ) if( cl.decal_index[id] == 0 ) { Image_SetForceFlags( IL_LOAD_DECAL ); - cl.decal_index[id] = GL_LoadTexture( host.draw_decals[id], NULL, 0, TF_DECAL ); + cl.decal_index[id] = ref.dllFuncs.GL_LoadTexture( host.draw_decals[id], NULL, 0, TF_DECAL ); Image_ClearForceFlags(); } @@ -3085,7 +3098,7 @@ remove all decals with specified texture void CL_DecalRemoveAll( int textureIndex ) { int id = bound( 0, textureIndex, MAX_DECALS - 1 ); - R_DecalRemoveAll( cl.decal_index[id] ); + ref.dllFuncs.R_DecalRemoveAll( cl.decal_index[id] ); } /* @@ -3114,6 +3127,29 @@ void CL_ClearEfrags( void ) clgame.free_efrags[i].entnext = &clgame.free_efrags[i+1]; clgame.free_efrags[i].entnext = NULL; } + +/* +======================= +R_ClearStaticEntities + +e.g. by demo request +======================= +*/ +void CL_ClearStaticEntities( void ) +{ + int i; + + if( host.type == HOST_DEDICATED ) + return; + + // 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; + + clgame.numStatics = 0; + + CL_ClearEfrags (); +} /* ============== @@ -3129,3 +3165,4 @@ void CL_ClearEffects( void ) CL_ClearParticles (); CL_ClearLightStyles (); } + diff --git a/engine/client/cl_tent.h b/engine/client/cl_tent.h index 6c991ec7..1cae7155 100644 --- a/engine/client/cl_tent.h +++ b/engine/client/cl_tent.h @@ -89,6 +89,9 @@ void CL_DecalRemoveAll( int textureIndex ); int CL_DecalIndexFromName( const char *name ); int CL_DecalIndex( int id ); +// RefAPI +struct particle_s *CL_AllocParticleFast( void ); + // Beams struct beam_s *R_BeamLightning( vec3_t start, vec3_t end, int modelIndex, float life, float width, float amplitude, float brightness, float speed ); struct beam_s *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 ); @@ -101,20 +104,16 @@ void R_BeamKill( int deadEntity ); // TriAPI -void TriBegin( int mode ); -void TriTexCoord2f( float u, float v ); -void TriVertex3fv( const float *v ); -void TriVertex3f( float x, float y, float z ); -int TriBoxInPVS( float *mins, float *maxs ); +void TriRenderMode( int mode ); void TriColor4f( float r, float g, float b, float a ); -int TriSpriteTexture( model_t *pSpriteModel, int frame ); -void TriColor4fRendermode( float r, float g, float b, float a, int rendermode ); -int TriWorldToScreen( float *world, float *screen ); void TriColor4ub( byte r, byte g, byte b, byte a ); void TriBrightness( float brightness ); -void TriRenderMode( int mode ); void TriCullFace( TRICULLSTYLE mode ); -void TriEnd( void ); +int TriWorldToScreen( const float *world, float *screen ); +int TriBoxInPVS( float *mins, float *maxs ); +void TriLightAtPoint( float *pos, float *value ); +void TriColor4fRendermode( float r, float g, float b, float a, int rendermode ); +int TriSpriteTexture( model_t *pSpriteModel, int frame ); extern model_t *cl_sprite_dot; extern model_t *cl_sprite_shell; diff --git a/engine/client/cl_video.c b/engine/client/cl_video.c index d386ac20..87bc933a 100644 --- a/engine/client/cl_video.c +++ b/engine/client/cl_video.c @@ -15,7 +15,6 @@ GNU General Public License for more details. #include "common.h" #include "client.h" -#include "gl_local.h" /* ================================================================= @@ -180,7 +179,7 @@ qboolean SCR_DrawCinematic( void ) qboolean redraw = false; byte *frame = NULL; - if( !glw_state.initialized || cin_time <= 0.0f ) + if( !ref.initialized || cin_time <= 0.0f ) return false; if( cin_frame != last_frame ) @@ -190,7 +189,7 @@ qboolean SCR_DrawCinematic( void ) redraw = true; } - R_DrawStretchRaw( 0, 0, glState.width, glState.height, xres, yres, frame, redraw ); + ref.dllFuncs.R_DrawStretchRaw( 0, 0, refState.width, refState.height, xres, yres, frame, redraw ); return true; } diff --git a/engine/client/cl_view.c b/engine/client/cl_view.c index 0e93b736..8902766e 100644 --- a/engine/client/cl_view.c +++ b/engine/client/cl_view.c @@ -17,9 +17,9 @@ GNU General Public License for more details. #include "client.h" #include "const.h" #include "entity_types.h" -#include "gl_local.h" #include "vgui_draw.h" #include "sound.h" +#include "platform/platform.h" // GL_UpdateSwapInterval /* =============== @@ -59,17 +59,17 @@ void V_CalcViewRect( void ) } size /= 100.0; - clgame.viewport[2] = glState.width * size; - clgame.viewport[3] = glState.height * size; + clgame.viewport[2] = refState.width * size; + clgame.viewport[3] = refState.height * size; - if( clgame.viewport[3] > glState.height - sb_lines ) - clgame.viewport[3] = glState.height - sb_lines; - if( clgame.viewport[3] > glState.height ) - clgame.viewport[3] = glState.height; + if( clgame.viewport[3] > refState.height - sb_lines ) + clgame.viewport[3] = refState.height - sb_lines; + if( clgame.viewport[3] > refState.height ) + clgame.viewport[3] = refState.height; - clgame.viewport[0] = ( glState.width - clgame.viewport[2] ) / 2; + clgame.viewport[0] = ( refState.width - clgame.viewport[2] ) / 2; if( full ) clgame.viewport[1] = 0; - else clgame.viewport[1] = ( glState.height - sb_lines - clgame.viewport[3] ) / 2; + else clgame.viewport[1] = ( refState.height - sb_lines - clgame.viewport[3] ) / 2; } @@ -113,8 +113,8 @@ void V_SetRefParams( ref_params_t *fd ) memset( fd, 0, sizeof( ref_params_t )); // probably this is not needs - VectorCopy( RI.vieworg, fd->vieworg ); - VectorCopy( RI.viewangles, fd->viewangles ); + VectorCopy( refState.vieworg, fd->vieworg ); + VectorCopy( refState.viewangles, fd->viewangles ); fd->frametime = host.frametime; fd->time = cl.time; @@ -183,7 +183,7 @@ void V_RefApplyOverview( ref_viewpass_t *rvp ) return; // NOTE: Xash3D may use 16:9 or 16:10 aspects - aspect = (float)glState.width / (float)glState.height; + aspect = (float)refState.width / (float)refState.height; size_x = fabs( 8192.0f / ov->flZoom ); size_y = fabs( 8192.0f / (ov->flZoom * aspect )); @@ -216,7 +216,7 @@ void V_RefApplyOverview( ref_viewpass_t *rvp ) SetBits( rvp->flags, RF_DRAW_OVERVIEW ); - Mod_SetOrthoBounds( mins, maxs ); + ref.dllFuncs.GL_OrthoBounds( mins, maxs ); } /* @@ -254,7 +254,7 @@ void V_GetRefParams( ref_params_t *fd, ref_viewpass_t *rvp ) rvp->fov_y = V_CalcFov( &rvp->fov_x, clgame.viewport[2], clgame.viewport[3] ); // adjust FOV for widescreen - if( glState.wideScreen && r_adjust_fov->value ) + if( refState.wideScreen && r_adjust_fov->value ) V_AdjustFov( &rvp->fov_x, &rvp->fov_y, clgame.viewport[2], clgame.viewport[3], false ); rvp->flags = 0; @@ -273,7 +273,7 @@ V_PreRender qboolean V_PreRender( void ) { // too early - if( !glw_state.initialized ) + if( !ref.initialized ) return false; if( host.status == HOST_NOFOCUS ) @@ -293,7 +293,9 @@ qboolean V_PreRender( void ) return false; } - R_BeginFrame( !cl.paused ); + ref.dllFuncs.R_BeginFrame( !cl.paused ); + + GL_UpdateSwapInterval( ); return true; } @@ -318,9 +320,9 @@ void V_RenderView( void ) V_CalcViewRect (); // compute viewport rectangle V_SetRefParams( &rp ); V_SetupViewModel (); - R_Set2DMode( false ); + ref.dllFuncs.R_Set2DMode( false ); SCR_DirtyScreen(); - GL_BackendStartFrame (); + ref.dllFuncs.GL_BackendStartFrame (); do { @@ -330,11 +332,10 @@ void V_RenderView( void ) if( viewnum == 0 && FBitSet( rvp.flags, RF_ONLY_CLIENTDRAW )) { - pglClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); - pglClear( GL_COLOR_BUFFER_BIT ); + ref.dllFuncs.R_ClearScreen(); } - R_RenderFrame( &rvp ); + ref.dllFuncs.GL_RenderFrame( &rvp ); S_UpdateFrame( &rvp ); viewnum++; @@ -342,7 +343,7 @@ void V_RenderView( void ) // draw debug triangles on a server SV_DrawDebugTriangles (); - GL_BackendEndFrame (); + ref.dllFuncs.GL_BackendEndFrame (); } /* @@ -356,8 +357,8 @@ void V_PostRender( void ) static double oldtime; qboolean draw_2d = false; - R_AllowFog( false ); - R_Set2DMode( true ); + ref.dllFuncs.R_AllowFog( false ); + ref.dllFuncs.R_Set2DMode( true ); if( cls.state == ca_active && cls.signon == SIGNONS && cls.scrshot_action != scrshot_mapshot ) { @@ -383,8 +384,8 @@ void V_PostRender( void ) SV_DrawOrthoTriangles(); CL_DrawDemoRecording(); CL_DrawHUD( CL_CHANGELEVEL ); - R_ShowTextures(); - R_ShowTree(); + ref.dllFuncs.R_ShowTextures(); + ref.dllFuncs.R_ShowTree(); Con_DrawConsole(); UI_UpdateMenu( host.realtime ); Con_DrawVersion(); @@ -394,6 +395,6 @@ void V_PostRender( void ) } SCR_MakeScreenShot(); - R_AllowFog( true ); - R_EndFrame(); + ref.dllFuncs.R_AllowFog( true ); + ref.dllFuncs.R_EndFrame(); } diff --git a/engine/client/client.h b/engine/client/client.h index ebdeae01..8b3df9e3 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -31,20 +31,7 @@ GNU General Public License for more details. #include "netchan.h" #include "net_api.h" #include "world.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 +#include "ref_common.h" // client sprite types #define SPR_CLIENT 0 // client sprite for temp-entities or user-textures @@ -53,13 +40,6 @@ GNU General Public License for more details. typedef int sound_t; -typedef enum -{ - DEMO_INACTIVE = 0, - DEMO_XASH3D, - DEMO_QUAKE1 -} demo_mode; - //============================================================================= typedef struct netbandwithgraph_s { @@ -166,13 +146,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; @@ -237,7 +210,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; @@ -303,16 +275,6 @@ of server connections ================================================================== */ -typedef enum -{ - ca_disconnected = 0,// not talking to a server - ca_connecting, // sending request packets to the server - ca_connected, // netchan_t established, waiting for svc_serverdata - ca_validate, // download resources, validating, auth on server - ca_active, // game views should be displayed - ca_cinematic, // playing a cinematic, not connected to a server -} connstate_t; - typedef enum { scrshot_inactive, @@ -378,7 +340,7 @@ typedef struct qboolean adjust_size; // allow to adjust scale for fonts int renderMode; // override kRenderMode from TriAPI - int cullMode; // override CULL FACE from TriAPI + TRICULLSTYLE cullMode; // override CULL FACE from TriAPI // holds text color rgba_t textColor; @@ -446,16 +408,6 @@ typedef struct float applied_angle; } screen_shake_t; -typedef struct -{ - unsigned short textures[MAX_SKINS];// alias textures - struct mstudiotex_s *ptexture; // array of textures with local copy of remapped textures - short numtextures; // textures count - short topcolor; // cached value - short bottomcolor; // cached value - model_t *model; // for catch model changes -} remap_info_t; - typedef enum { NET_REQUEST_CANCEL = 0, // request was cancelled for some reasons @@ -735,6 +687,8 @@ extern convar_t *m_ignore; void CL_SetLightstyle( int style, const char* s, float f ); void CL_RunLightStyles( void ); void CL_DecayLights( void ); +dlight_t *CL_GetDynamicLight( int number ); +dlight_t *CL_GetEntityLight( int number ); //================================================= @@ -751,7 +705,6 @@ void CL_SaveShot_f( void ); void CL_LevelShot_f( void ); void CL_SetSky_f( void ); void SCR_Viewpos_f( void ); -void SCR_TimeRefresh_f( void ); // // cl_custom.c @@ -771,6 +724,11 @@ void CL_ResetFrame( frame_t *frame ); void CL_WriteMessageHistory( void ); const char *CL_MsgInfo( int cmd ); +// +// cl_efx.c +// +void CL_Particle( const vec3_t org, int color, float life, int zpos, int zvel ); + // // cl_main.c // @@ -864,6 +822,11 @@ void CL_PlayerTrace( float *start, float *end, int traceFlags, int ignore_pe, pm void CL_PlayerTraceExt( float *start, float *end, int traceFlags, int (*pfnIgnore)( physent_t *pe ), pmtrace_t *tr ); void CL_SetTraceHull( int hull ); void CL_GetMousePosition( int *mx, int *my ); // TODO: move to input +cl_entity_t* CL_GetViewModel( void ); +void pfnGetScreenFade( struct screenfade_s *fade ); +physent_t *pfnGetPhysent( int idx ); +struct msurface_s *pfnTraceSurface( int ground, float *vstart, float *vend ); +movevars_t *pfnGetMoveVars( void ); _inline cl_entity_t *CL_EDICT_NUM( int n ) { @@ -954,11 +917,6 @@ void CL_SetUpPlayerPrediction( int dopred, int bIncludeLocalClient ); // void CL_ParseQuakeMessage( sizebuf_t *msg, qboolean normal_message ); -// -// cl_studio.c -// -void CL_InitStudioAPI( void ); - // // cl_frame.c // @@ -983,10 +941,24 @@ void CL_EmitEntities( void ); remap_info_t *CL_GetRemapInfoForEntity( cl_entity_t *e ); void CL_AllocRemapInfo( int topcolor, int bottomcolor ); void CL_FreeRemapInfo( remap_info_t *info ); -void R_StudioSetRemapColors( int top, int bottom ); void CL_UpdateRemapInfo( int topcolor, int bottomcolor ); void CL_ClearAllRemaps( void ); +// +// cl_render.c +// +qboolean R_InitRenderAPI( void ); +int CL_RenderGetParm( const int parm, const int arg, const qboolean checkRef ); +lightstyle_t *CL_GetLightStyle( int number ); +int R_FatPVS( const vec3_t org, float radius, byte *visbuffer, qboolean merge, qboolean fullvis ); +const ref_overview_t *GL_GetOverviewParms( void ); + +// +// cl_efrag.c +// +void R_StoreEfrags( efrag_t **ppefrag, int framecount ); +void R_AddEfrags( cl_entity_t *ent ); +void R_RemoveEfrags( cl_entity_t *ent ); // // cl_tent.c // @@ -996,7 +968,6 @@ void CL_WeaponAnim( int iAnim, int body ); void CL_ClearEffects( void ); void CL_ClearEfrags( void ); void CL_TestLights( void ); -void CL_DrawParticlesExternal( const ref_viewpass_t *rvp, qboolean trans_pass, float frametime ); void CL_FireCustomDecal( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags, float scale ); void CL_DecalShoot( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags ); void CL_PlayerDecal( int playerIndex, int textureIndex, int entityIndex, float *pos ); @@ -1007,8 +978,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,12 +985,13 @@ 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 ); +cl_entity_t *R_BeamGetEntity( int index ); void CL_KillDeadBeams( cl_entity_t *pDeadEntity ); void CL_ParseViewBeam( sizebuf_t *msg, int beamType ); void CL_LoadClientSprites( void ); void CL_ReadPointFile_f( void ); +void CL_DrawEFX( float time, qboolean fTrans ); +void CL_ThinkParticle( double frametime, particle_t *p ); void CL_ReadLineFile_f( void ); void CL_RunLightStyles( void ); diff --git a/engine/client/console.c b/engine/client/console.c index 080b663c..882e6816 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -18,7 +18,6 @@ GNU General Public License for more details. #include "keydefs.h" #include "protocol.h" // get the protocol version #include "con_nprint.h" -#include "gl_local.h" #include "qfont.h" #include "wadfile.h" @@ -443,8 +442,8 @@ void Con_CheckResize( void ) if( con.curFont && con.curFont->hFontTexture ) charWidth = con.curFont->charWidths['O'] - 1; - width = ( glState.width / charWidth ) - 2; - if( !glw_state.initialized ) width = (640 / 5); + width = ( refState.width / charWidth ) - 2; + if( !ref.initialized ) width = (640 / 5); if( width == con.linewidth ) return; @@ -532,7 +531,7 @@ static qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font ) return false; // keep source to print directly into conback image - font->hFontTexture = GL_LoadTexture( fontname, NULL, 0, TF_FONT|TF_KEEP_SOURCE ); + font->hFontTexture = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, TF_FONT|TF_KEEP_SOURCE ); R_GetTextureParms( &fontWidth, NULL, font->hFontTexture ); if( font->hFontTexture && fontWidth != 0 ) @@ -568,7 +567,7 @@ static qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font if( !FS_FileExists( fontname, false )) return false; - font->hFontTexture = GL_LoadTexture( fontname, NULL, 0, TF_FONT|TF_NEAREST ); + font->hFontTexture = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, TF_FONT|TF_NEAREST ); R_GetTextureParms( &fontWidth, NULL, font->hFontTexture ); // setup consolefont @@ -651,9 +650,9 @@ static void Con_LoadConchars( void ) Con_LoadConsoleFont( i, con.chars + i ); // select properly fontsize - if( glState.width <= 640 ) + if( refState.width <= 640 ) fontSize = 0; - else if( glState.width >= 1280 ) + else if( refState.width >= 1280 ) fontSize = 2; else fontSize = 1; @@ -805,7 +804,7 @@ int Con_UtfMoveRight( char *str, int pos, int length ) return pos+1; } -static void Con_DrawCharToConback( int num, byte *conchars, byte *dest ) +static void Con_DrawCharToConback( int num, const byte *conchars, byte *dest ) { int row, col; byte *source; @@ -843,8 +842,8 @@ static void Con_TextAdjustSize( int *x, int *y, int *w, int *h ) if( !x && !y && !w && !h ) return; // scale for screen sizes - xscale = (float)glState.width / (float)clgame.scrInfo.iWidth; - yscale = (float)glState.height / (float)clgame.scrInfo.iHeight; + xscale = (float)refState.width / (float)clgame.scrInfo.iWidth; + yscale = (float)refState.height / (float)clgame.scrInfo.iHeight; if( x ) *x *= xscale; if( y ) *y *= yscale; @@ -863,7 +862,6 @@ static int Con_DrawGenericChar( int x, int y, int number, rgba_t color ) { int width, height; float s1, t1, s2, t2; - gl_texture_t *glt; wrect_t *rc; number &= 255; @@ -879,18 +877,15 @@ static int Con_DrawGenericChar( int x, int y, int number, rgba_t color ) return 0; rc = &con.curFont->fontRc[number]; - glt = R_GetTexture( con.curFont->hFontTexture ); - width = glt->srcWidth; - height = glt->srcHeight; + R_GetTextureParms( &width, &height, con.curFont->hFontTexture ); if( !width || !height ) return con.curFont->charWidths[number]; // don't apply color to fixed fonts it's already colored - if( con.curFont->type != FONT_FIXED || glt->format == GL_LUMINANCE8_ALPHA8 ) - pglColor4ubv( color ); - else pglColor4ub( 255, 255, 255, color[3] ); - R_GetTextureParms( &width, &height, con.curFont->hFontTexture ); + if( con.curFont->type != FONT_FIXED || REF_GET_PARM( PARM_TEX_GLFORMAT, 0x8045 ) ) // GL_LUMINANCE8_ALPHA8 + ref.dllFuncs.Color4ub( color[0], color[1], color[2], color[3] ); + else ref.dllFuncs.Color4ub( 255, 255, 255, color[3] ); // calc rectangle s1 = (float)rc->left / width; @@ -902,8 +897,8 @@ static int Con_DrawGenericChar( int x, int y, int number, rgba_t color ) if( clgame.ds.adjust_size ) Con_TextAdjustSize( &x, &y, &width, &height ); - R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, con.curFont->hFontTexture ); - pglColor4ub( 255, 255, 255, 255 ); // don't forget reset color + ref.dllFuncs.R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, con.curFont->hFontTexture ); + ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); // don't forget reset color return con.curFont->charWidths[number]; } @@ -943,7 +938,7 @@ client version of routine */ int Con_DrawCharacter( int x, int y, int number, rgba_t color ) { - GL_SetRenderMode( kRenderTransTexture ); + ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture ); return Con_DrawGenericChar( x, y, number, color ); } @@ -1064,7 +1059,7 @@ int Con_DrawGenericString( int x, int y, const char *string, rgba_t setColor, qb s++; } - pglColor4ub( 255, 255, 255, 255 ); + ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); return drawLen; } @@ -1627,10 +1622,12 @@ void Field_DrawInputLine( int x, int y, field_t *edit ) if( host.key_overstrike && cursorChar ) { // overstrike cursor +#if 0 pglEnable( GL_BLEND ); pglDisable( GL_ALPHA_TEST ); pglBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA ); pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); +#endif Con_DrawGenericChar( x + curPos, y, cursorChar, colorDefault ); } else @@ -1854,7 +1851,7 @@ int Con_DrawDebugLines( void ) int defaultX; int y = 20; - defaultX = glState.width / 4; + defaultX = refState.width / 4; for( i = 0; i < MAX_DBG_NOTIFY; i++ ) { @@ -1864,10 +1861,10 @@ int Con_DrawDebugLines( void ) int fontTall; Con_DrawStringLen( con.notify[i].szNotify, &len, &fontTall ); - x = glState.width - Q_max( defaultX, len ) - 10; + x = refState.width - Q_max( defaultX, len ) - 10; fontTall += 1; - if( y + fontTall > glState.height - 20 ) + if( y + fontTall > refState.height - 20 ) return count; count++; @@ -1896,7 +1893,7 @@ void Con_DrawDebug( void ) { Q_snprintf( dlstring, sizeof( dlstring ), "Downloading [%d remaining]: ^2%s^7 %5.1f%% time %.f secs", host.downloadcount, host.downloadfile, scr_download->value, Sys_DoubleTime() - timeStart ); - x = glState.width - 500; + x = refState.width - 500; y = con.curFont->charHeight * 1.05f; Con_DrawString( x, y, dlstring, g_color_table[7] ); } @@ -1962,7 +1959,7 @@ void Con_DrawNotify( void ) Field_DrawInputLine( x + len, y, &con.chat ); } - pglColor4ub( 255, 255, 255, 255 ); + ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); } /* @@ -2034,9 +2031,9 @@ void Con_DrawSolidConsole( int lines ) if( lines <= 0 ) return; // draw the background - GL_SetRenderMode( kRenderNormal ); - pglColor4ub( 255, 255, 255, 255 ); // to prevent grab color from screenfade - R_DrawStretchPic( 0, lines - glState.width * 3 / 4, glState.width, glState.width * 3 / 4, 0, 0, 1, 1, con.background ); + ref.dllFuncs.GL_SetRenderMode( kRenderNormal ); + ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); // to prevent grab color from screenfade + ref.dllFuncs.R_DrawStretchPic( 0, lines - refState.width * 3 / 4, refState.width, refState.width * 3 / 4, 0, 0, 1, 1, con.background ); if( !con.curFont || !host.allow_console ) return; // nothing to draw @@ -2054,10 +2051,10 @@ void Con_DrawSolidConsole( int lines ) Q_snprintf( curbuild, MAX_STRING, "%s %i/%s (%s-%s build %i)", XASH_ENGINE_NAME, PROTOCOL_VERSION, XASH_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( )); Con_DrawStringLen( curbuild, &stringLen, &charH ); - start = glState.width - stringLen; + start = refState.width - stringLen; stringLen = Con_StringLength( curbuild ); - fraction = lines / (float)glState.height; + fraction = lines / (float)refState.height; color[3] = Q_min( fraction * 2.0f, 1.0f ) * 255; // fadeout version number for( i = 0; i < stringLen; i++ ) @@ -2101,7 +2098,7 @@ void Con_DrawSolidConsole( int lines ) y = lines - ( con.curFont->charHeight * 1.2f ); SCR_DrawFPS( max( y, 4 )); // to avoid to hide fps counter - pglColor4ub( 255, 255, 255, 255 ); + ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); } /* @@ -2124,7 +2121,7 @@ void Con_DrawConsole( void ) { if(( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )) && cls.key_dest != key_console ) con.vislines = con.showlines = 0; - else con.vislines = con.showlines = glState.height; + else con.vislines = con.showlines = refState.height; } else { @@ -2141,7 +2138,7 @@ void Con_DrawConsole( void ) case ca_disconnected: if( cls.key_dest != key_menu ) { - Con_DrawSolidConsole( glState.height ); + Con_DrawSolidConsole( refState.height ); Key_SetKeyDest( key_console ); } break; @@ -2156,7 +2153,7 @@ void Con_DrawConsole( void ) if( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )) { if( cls.key_dest == key_console ) - Con_DrawSolidConsole( glState.height ); + Con_DrawSolidConsole( refState.height ); } else { @@ -2183,7 +2180,7 @@ void Con_DrawVersion( void ) // draws the current build byte *color = g_color_table[7]; int i, stringLen, width = 0, charH; - int start, height = glState.height; + int start, height = refState.height; qboolean draw_version = false; string curbuild; @@ -2209,7 +2206,7 @@ void Con_DrawVersion( void ) else Q_snprintf( curbuild, MAX_STRING, "v%i/%s (%s-%s build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( )); Con_DrawStringLen( curbuild, &stringLen, &charH ); - start = glState.width - stringLen * 1.05f; + start = refState.width - stringLen * 1.05f; stringLen = Con_StringLength( curbuild ); height -= charH * 1.05f; @@ -2232,8 +2229,8 @@ void Con_RunConsole( void ) if( host.allow_console && cls.key_dest == key_console ) { if( cls.state < ca_active || cl.first_frame ) - con.showlines = glState.height; // full screen - else con.showlines = (glState.height >> 1); // half screen + con.showlines = refState.height; // full screen + else con.showlines = (refState.height >> 1); // half screen } else con.showlines = 0; // none visible @@ -2322,28 +2319,28 @@ void Con_VidInit( void ) { // trying to load truecolor image first if( FS_FileExists( "gfx/shell/conback.bmp", false ) || FS_FileExists( "gfx/shell/conback.tga", false )) - con.background = GL_LoadTexture( "gfx/shell/conback", NULL, 0, TF_IMAGE ); + con.background = ref.dllFuncs.GL_LoadTexture( "gfx/shell/conback", NULL, 0, TF_IMAGE ); if( !con.background ) { if( FS_FileExists( "cached/conback640", false )) - con.background = GL_LoadTexture( "cached/conback640", NULL, 0, TF_IMAGE ); + con.background = ref.dllFuncs.GL_LoadTexture( "cached/conback640", NULL, 0, TF_IMAGE ); else if( FS_FileExists( "cached/conback", false )) - con.background = GL_LoadTexture( "cached/conback", NULL, 0, TF_IMAGE ); + con.background = ref.dllFuncs.GL_LoadTexture( "cached/conback", NULL, 0, TF_IMAGE ); } } else { // trying to load truecolor image first if( FS_FileExists( "gfx/shell/loading.bmp", false ) || FS_FileExists( "gfx/shell/loading.tga", false )) - con.background = GL_LoadTexture( "gfx/shell/loading", NULL, 0, TF_IMAGE ); + con.background = ref.dllFuncs.GL_LoadTexture( "gfx/shell/loading", NULL, 0, TF_IMAGE ); if( !con.background ) { if( FS_FileExists( "cached/loading640", false )) - con.background = GL_LoadTexture( "cached/loading640", NULL, 0, TF_IMAGE ); + con.background = ref.dllFuncs.GL_LoadTexture( "cached/loading640", NULL, 0, TF_IMAGE ); else if( FS_FileExists( "cached/loading", false )) - con.background = GL_LoadTexture( "cached/loading", NULL, 0, TF_IMAGE ); + con.background = ref.dllFuncs.GL_LoadTexture( "cached/loading", NULL, 0, TF_IMAGE ); } } @@ -2352,7 +2349,7 @@ void Con_VidInit( void ) { qboolean draw_to_console = false; int length = 0; - gl_texture_t *chars; + byte *buf; // NOTE: only these games want to draw build number into console background if( !Q_stricmp( FS_Gamedir(), "id1" )) @@ -2364,7 +2361,8 @@ void Con_VidInit( void ) if( !Q_stricmp( FS_Gamedir(), "rogue" )) draw_to_console = true; - if( draw_to_console && con.curFont && ( chars = R_GetTexture( con.curFont->hFontTexture )) != NULL && chars->original ) + if( draw_to_console && con.curFont && + ( buf = ref.dllFuncs.R_GetTextureOriginalBuffer( con.curFont->hFontTexture )) != NULL ) { lmp_t *cb = (lmp_t *)FS_LoadFile( "gfx/conback.lmp", &length, false ); char ver[64]; @@ -2377,19 +2375,19 @@ void Con_VidInit( void ) dest = (byte *)(cb + 1) + 320 * 186 + 320 - 11 - 8 * Q_strlen( ver ); y = Q_strlen( ver ); for( x = 0; x < y; x++ ) - Con_DrawCharToConback( ver[x], chars->original->buffer, dest + (x << 3)); - con.background = GL_LoadTexture( "#gfx/conback.lmp", (byte *)cb, length, TF_IMAGE ); + Con_DrawCharToConback( ver[x], buf, dest + (x << 3)); + con.background = ref.dllFuncs.GL_LoadTexture( "#gfx/conback.lmp", (byte *)cb, length, TF_IMAGE ); } if( cb ) Mem_Free( cb ); } if( !con.background ) // trying the load unmodified conback - con.background = GL_LoadTexture( "gfx/conback.lmp", NULL, 0, TF_IMAGE ); + con.background = ref.dllFuncs.GL_LoadTexture( "gfx/conback.lmp", NULL, 0, TF_IMAGE ); } // missed console image will be replaced as gray background like X-Ray or Crysis - if( con.background == tr.defaultTexture || con.background == 0 ) - con.background = tr.grayTexture; + if( con.background == ref.dllFuncs.R_GetBuiltinTexture( REF_DEFAULT_TEXTURE ) || con.background == 0 ) + con.background = ref.dllFuncs.R_GetBuiltinTexture( REF_GRAY_TEXTURE ); } /* diff --git a/engine/client/in_joy.c b/engine/client/in_joy.c index 53ec5ba5..46de098d 100644 --- a/engine/client/in_joy.c +++ b/engine/client/in_joy.c @@ -20,7 +20,6 @@ GNU General Public License for more details. #include "input.h" #include "keydefs.h" #include "client.h" -#include "gl_local.h" #include "platform/platform.h" #ifndef SHRT_MAX diff --git a/engine/client/in_touch.c b/engine/client/in_touch.c deleted file mode 100644 index 4c38088c..00000000 --- a/engine/client/in_touch.c +++ /dev/null @@ -1,1766 +0,0 @@ -/* -touch.c - touchscreen support prototype -Copyright (C) 2015 a1batross - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -*/ - -#ifndef XASH_DEDICATED -#include "common.h" -#include "gl_local.h" -#include "input.h" -#include "mobility_int.h" -#include "client.h" -#include "math.h" -#include "vgui_draw.h" -#ifdef XASH_SDL -#include -#endif -#include "platform/platform.h" - -typedef enum -{ - touch_command, // Just tap a button - touch_move, // Like a joystick stick. - touch_joy, // Like a joystick stick, centered. - touch_dpad, // Only two directions. - touch_look // Like a touchpad. -} touchButtonType; - -typedef enum -{ - state_none = 0, - state_edit, - state_edit_move -} touchState; - -typedef enum -{ - round_none = 0, - round_grid, - round_aspect -} touchRound; - - - -typedef struct touchbutton2_s -{ - // Touch button type: tap, stick or slider - touchButtonType type; - // Field of button in pixels - float x1, y1, x2, y2; - // Button texture - int texture; - rgba_t color; - char texturefile[256]; - char command[256]; - char name[32]; - int finger; - int flags; - float fade; - float fadespeed; - float fadeend; - float aspect; - // Double-linked list - struct touchbutton2_s *next; - struct touchbutton2_s *prev; - -} touchbutton2_t; - -typedef struct touchdefaultbutton_s -{ - char name[32]; - char texturefile[256]; - char command[256]; - float x1, y1, x2, y2; - rgba_t color; - touchRound round; - float aspect; - int flags; -} touchdefaultbutton_t; - -typedef struct touchbuttonlist_s -{ - touchbutton2_t *first; - touchbutton2_t *last; -} touchbuttonlist_t; - -struct touch_s -{ - qboolean initialized; - touchbuttonlist_t list_user; - byte *mempool; - touchState state; - int look_finger; - int move_finger; - touchbutton2_t *move; - float move_start_x; - float move_start_y; - float forward; - float side; - float yaw; - float pitch; - // editing - touchbutton2_t *edit; - touchbutton2_t *selection; - int resize_finger; - qboolean showbuttons; - qboolean clientonly; - rgba_t scolor; - int swidth; - qboolean precision; - // textures - int showtexture; - int hidetexture; - int resettexture; - int closetexture; - int joytexture; // touch indicator - qboolean configchanged; -} touch; - -touchdefaultbutton_t g_DefaultButtons[256]; -int g_LastDefaultButton; - -convar_t *touch_pitch; -convar_t *touch_yaw; -convar_t *touch_forwardzone; -convar_t *touch_sidezone; -convar_t *touch_nonlinear_look; -convar_t *touch_pow_mult; -convar_t *touch_pow_factor; -convar_t *touch_exp_mult; -convar_t *touch_grid_enable; -convar_t *touch_grid_count; -convar_t *touch_config_file; -convar_t *touch_enable; -convar_t *touch_in_menu; -convar_t *touch_joy_radius; -convar_t *touch_dpad_radius; -convar_t *touch_move_indicator; -convar_t *touch_highlight_r; -convar_t *touch_highlight_g; -convar_t *touch_highlight_b; -convar_t *touch_highlight_a; -convar_t *touch_precise_amount; -convar_t *touch_joy_texture; - -// code looks smaller with it -#define B(x) button->x -#define SCR_W ((float)glState.width) -#define SCR_H ((float)glState.height) -#define TO_SCRN_Y(x) (glState.height * (x)) -#define TO_SCRN_X(x) (glState.width * (x)) - - -int pfnDrawCharacter( int x, int y, int number, int r, int g, int b ); -static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 ); - -void IN_TouchWriteConfig( void ) -{ - file_t *f; - char newconfigfile[64]; - char oldconfigfile[64]; - - if( !touch.list_user.first ) return; - - if( Sys_CheckParm( "-nowriteconfig" ) || !touch.configchanged ) - return; - - Con_Reportf( "IN_TouchWriteConfig(): %s\n", touch_config_file->string ); - - Q_snprintf( newconfigfile, 64, "%s.new", touch_config_file->string ); - Q_snprintf( oldconfigfile, 64, "%s.bak", touch_config_file->string ); - - f = FS_Open( newconfigfile, "w", true ); - if( f ) - { - touchbutton2_t *button; - FS_Printf( f, "//=======================================================================\n"); - FS_Printf( f, "//\tCopyright SDLash3D team & XashXT group %s ©\n", Q_timestamp( TIME_YEAR_ONLY )); - FS_Printf( f, "//\t\t\ttouchscreen config\n" ); - FS_Printf( f, "//=======================================================================\n" ); - FS_Printf( f, "\ntouch_config_file \"%s\"\n", touch_config_file->string ); - FS_Printf( f, "\n// touch cvars\n" ); - FS_Printf( f, "\n// sensitivity settings\n" ); - FS_Printf( f, "touch_pitch \"%f\"\n", touch_pitch->value ); - FS_Printf( f, "touch_yaw \"%f\"\n", touch_yaw->value ); - FS_Printf( f, "touch_forwardzone \"%f\"\n", touch_forwardzone->value ); - FS_Printf( f, "touch_sidezone \"%f\"\n", touch_sidezone->value ); - FS_Printf( f, "touch_nonlinear_look \"%d\"\n", (int)touch_nonlinear_look->value ); - FS_Printf( f, "touch_pow_factor \"%f\"\n", touch_pow_factor->value ); - FS_Printf( f, "touch_pow_mult \"%f\"\n", touch_pow_mult->value ); - FS_Printf( f, "touch_exp_mult \"%f\"\n", touch_exp_mult->value ); FS_Printf( f, "\n// grid settings\n" ); - FS_Printf( f, "touch_grid_count \"%d\"\n", (int)touch_grid_count->value ); - FS_Printf( f, "touch_grid_enable \"%d\"\n", (int)touch_grid_enable->value ); - FS_Printf( f, "\n// global overstroke (width, r, g, b, a)\n" ); - FS_Printf( f, "touch_set_stroke %d %d %d %d %d\n", touch.swidth, touch.scolor[0], touch.scolor[1], touch.scolor[2], touch.scolor[3] ); - FS_Printf( f, "\n// highlight when pressed\n" ); - FS_Printf( f, "touch_highlight_r \"%f\"\n", touch_highlight_r->value ); - FS_Printf( f, "touch_highlight_g \"%f\"\n", touch_highlight_g->value ); - FS_Printf( f, "touch_highlight_b \"%f\"\n", touch_highlight_b->value ); - FS_Printf( f, "touch_highlight_a \"%f\"\n", touch_highlight_a->value ); - FS_Printf( f, "\n// _joy and _dpad options\n" ); - FS_Printf( f, "touch_dpad_radius \"%f\"\n", touch_dpad_radius->value ); - FS_Printf( f, "touch_joy_radius \"%f\"\n", touch_joy_radius->value ); - FS_Printf( f, "\n// how much slowdown when Precise Look button pressed\n" ); - FS_Printf( f, "touch_precise_amount \"%f\"\n", touch_precise_amount->value ); - FS_Printf( f, "\n// enable/disable move indicator\n" ); - FS_Printf( f, "touch_move_indicator \"%d\"\n", (int)touch_move_indicator->value ); - - FS_Printf( f, "\n// reset menu state when execing config\n" ); - FS_Printf( f, "touch_setclientonly 0\n" ); - FS_Printf( f, "\n// touch buttons\n" ); - FS_Printf( f, "touch_removeall\n" ); - for( button = touch.list_user.first; button; button = button->next ) - { - int flags = button->flags; - if( flags & TOUCH_FL_CLIENT ) - continue; //skip temporary buttons - if( flags & TOUCH_FL_DEF_SHOW ) - flags &= ~TOUCH_FL_HIDE; - if( flags & TOUCH_FL_DEF_HIDE ) - flags |= TOUCH_FL_HIDE; - - FS_Printf( f, "touch_addbutton \"%s\" \"%s\" \"%s\" %f %f %f %f %d %d %d %d %d\n", - B(name), B(texturefile), B(command), - B(x1), B(y1), B(x2), B(y2), - B(color[0]), B(color[1]), B(color[2]), B(color[3]), flags ); - } - - FS_Close( f ); - FS_Delete( oldconfigfile ); - FS_Rename( touch_config_file->string, oldconfigfile ); - FS_Delete( touch_config_file->string ); - FS_Rename( newconfigfile, touch_config_file->string ); - } - else Con_Reportf( S_ERROR "Couldn't write %s.\n", touch_config_file->string ); -} - -void IN_TouchExportConfig_f( void ) -{ - file_t *f; - const char *name; - - if( Cmd_Argc() != 2 ) - { - Msg( S_USAGE "touch_exportconfig \n" ); - return; - } - - if( !touch.list_user.first ) return; - - name = Cmd_Argv( 1 ); - - Con_Reportf( "Exporting config to %s\n", name ); - f = FS_Open( name, "w", true ); - if( f ) - { - char profilename[256]; - char profilebase[256]; - touchbutton2_t *button; - if( Q_strstr( name, "touch_presets/" ) ) - { - COM_FileBase( name, profilebase ); - Q_snprintf( profilename, 256, "touch_profiles/%s (copy).cfg", profilebase ); - } - else Q_strncpy( profilename, name, 256 ); - FS_Printf( f, "//=======================================================================\n"); - FS_Printf( f, "//\tCopyright SDLash3D team & XashXT group %s ©\n", Q_timestamp( TIME_YEAR_ONLY )); - FS_Printf( f, "//\t\t\ttouchscreen preset\n" ); - FS_Printf( f, "//=======================================================================\n" ); - FS_Printf( f, "\ntouch_config_file \"%s\"\n", profilename ); - FS_Printf( f, "\n// touch cvars\n" ); - FS_Printf( f, "\n// sensitivity settings\n" ); - FS_Printf( f, "touch_pitch \"%f\"\n", touch_pitch->value ); - FS_Printf( f, "touch_yaw \"%f\"\n", touch_yaw->value ); - FS_Printf( f, "touch_forwardzone \"%f\"\n", touch_forwardzone->value ); - FS_Printf( f, "touch_sidezone \"%f\"\n", touch_sidezone->value ); - FS_Printf( f, "touch_nonlinear_look \"%d\"\n", (int)touch_nonlinear_look->value ); - FS_Printf( f, "touch_pow_factor \"%f\"\n", touch_pow_factor->value ); - FS_Printf( f, "touch_pow_mult \"%f\"\n", touch_pow_mult->value ); - FS_Printf( f, "touch_exp_mult \"%f\"\n", touch_exp_mult->value ); - FS_Printf( f, "\n// grid settings\n" ); - FS_Printf( f, "touch_grid_count \"%d\"\n", (int)touch_grid_count->value ); - FS_Printf( f, "touch_grid_enable \"%d\"\n", (int)touch_grid_enable->value ); - FS_Printf( f, "\n// global overstroke (width, r, g, b, a)\n" ); - FS_Printf( f, "touch_set_stroke %d %d %d %d %d\n", touch.swidth, touch.scolor[0], touch.scolor[1], touch.scolor[2], touch.scolor[3] ); - FS_Printf( f, "\n// highlight when pressed\n" ); - FS_Printf( f, "touch_highlight_r \"%f\"\n", touch_highlight_r->value ); - FS_Printf( f, "touch_highlight_g \"%f\"\n", touch_highlight_g->value ); - FS_Printf( f, "touch_highlight_b \"%f\"\n", touch_highlight_b->value ); - FS_Printf( f, "touch_highlight_a \"%f\"\n", touch_highlight_a->value ); - FS_Printf( f, "\n// _joy and _dpad options\n" ); - FS_Printf( f, "touch_dpad_radius \"%f\"\n", touch_dpad_radius->value ); - FS_Printf( f, "touch_joy_radius \"%f\"\n", touch_joy_radius->value ); - FS_Printf( f, "\n// how much slowdown when Precise Look button pressed\n" ); - FS_Printf( f, "touch_precise_amount \"%f\"\n", touch_precise_amount->value ); - FS_Printf( f, "\n// enable/disable move indicator\n" ); - FS_Printf( f, "touch_move_indicator \"%d\"\n", (int)touch_move_indicator->value ); - - FS_Printf( f, "\n// reset menu state when execing config\n" ); - FS_Printf( f, "touch_setclientonly 0\n" ); - FS_Printf( f, "\n// touch buttons\n" ); - FS_Printf( f, "touch_removeall\n" ); - for( button = touch.list_user.first; button; button = button->next ) - { - float aspect; - int flags = button->flags; - if( flags & TOUCH_FL_CLIENT ) - continue; //skip temporary buttons - if( flags & TOUCH_FL_DEF_SHOW ) - flags &= ~TOUCH_FL_HIDE; - if( flags & TOUCH_FL_DEF_HIDE ) - flags |= TOUCH_FL_HIDE; - - aspect = ( B(y2) - B(y1) ) / ( ( B(x2) - B(x1) ) /(SCR_H/SCR_W) ); - - FS_Printf( f, "touch_addbutton \"%s\" \"%s\" \"%s\" %f %f %f %f %d %d %d %d %d %f\n", - B(name), B(texturefile), B(command), - B(x1), B(y1), B(x2), B(y2), - B(color[0]), B(color[1]), B(color[2]), B(color[3]), flags, aspect ); - } - FS_Printf( f, "\n// round button coordinates to grid\n" ); - FS_Printf( f, "touch_roundall\n" ); - FS_Close( f ); - } - else Con_Reportf( S_ERROR "Couldn't write %s.\n", name ); -} - -void IN_TouchGenetateCode_f( void ) -{ - touchbutton2_t *button; - rgba_t c = {0,0,0,0}; - - if( Cmd_Argc() != 1 ) - { - Msg( S_USAGE "touch_generate_code\n" ); - return; - } - - if( !touch.list_user.first ) return; - - for( button = touch.list_user.first; button; button = button->next ) - { - float aspect; - int flags = button->flags; - if( flags & TOUCH_FL_CLIENT ) - continue; //skip temporary buttons - if( flags & TOUCH_FL_DEF_SHOW ) - flags &= ~TOUCH_FL_HIDE; - if( flags & TOUCH_FL_DEF_HIDE ) - flags |= TOUCH_FL_HIDE; - - aspect = ( B(y2) - B(y1) ) / ( ( B(x2) - B(x1) ) /(SCR_H/SCR_W) ); - if( memcmp( &c, &B(color), sizeof( rgba_t ) ) ) - { - Msg( "MakeRGBA( color, %d, %d, %d, %d );\n", B(color[0]), B(color[1]), B(color[2]), B(color[3]) ); - memcpy( &c, &B(color), sizeof( rgba_t ) ); - } - Msg( "TOUCH_ADDDEFAULT( \"%s\", \"%s\", \"%s\", %f, %f, %f, %f, color, %d, %f, %d );\n", - B(name), B(texturefile), B(command), - B(x1), B(y1), B(x2), B(y2), (B(type) == touch_command)?(fabs( aspect - 1.0f) < 0.0001)?2:1:0, aspect, flags ); - } -} - -void IN_TouchRoundAll_f( void ) -{ - touchbutton2_t *button; - if( !touch_grid_enable->value ) - return; - for( button = touch.list_user.first; button; button = button->next ) - IN_TouchCheckCoords( &B(x1), &B(y1), &B(x2), &B(y2) ); -} - -void IN_TouchListButtons_f( void ) -{ - touchbutton2_t *button; - for( button = touch.list_user.first; button; button = button->next ) - { - Msg( "%s %s %s %f %f %f %f %d %d %d %d %d\n", - B(name), B(texturefile), B(command), - B(x1), B(y1), B(x2), B(y2), - B(color[0]), B(color[1]), B(color[2]), B(color[3]), B(flags) ); - if( B(flags) & TOUCH_FL_CLIENT) - continue; - UI_AddTouchButtonToList( B(name), B(texturefile), B(command),B(color), B(flags) ); - } - touch.configchanged = true; -} - -void IN_TouchStroke_f( void ) -{ - touch.swidth = Q_atoi( Cmd_Argv( 1 ) ); - MakeRGBA( touch.scolor, Q_atoi( Cmd_Argv( 2 ) ), Q_atoi( Cmd_Argv( 3 ) ), Q_atoi( Cmd_Argv( 4 ) ), Q_atoi( Cmd_Argv( 5 ) ) ); -} - -touchbutton2_t *IN_TouchFindButton( touchbuttonlist_t *list, const char *name ) -{ - touchbutton2_t *button; - - for ( button = list->first; button; button = button->next ) - if( !Q_strncmp( button->name, name, 32 ) ) - return button; - return NULL; -} - -touchbutton2_t *IN_TouchFindFirst( touchbuttonlist_t *list, const char *name ) -{ - touchbutton2_t *button; - - for ( button = list->first; button; button = button->next ) - if( ( Q_strstr( name, "*" ) && Q_stricmpext( name, button->name ) ) || !Q_strncmp( name, button->name, 32 ) ) - return button; - return NULL; -} - -void IN_TouchSetClientOnly( qboolean state ) -{ - touch.clientonly = state; - host.mouse_visible = state; -#ifdef XASH_SDL - if( state ) - { - SDL_SetRelativeMouseMode( SDL_FALSE ); - SDL_ShowCursor( true ); - IN_DeactivateMouse(); - } - else - { - SDL_ShowCursor( false ); - SDL_GetRelativeMouseState( 0, 0 ); - } -#endif -} - -void IN_TouchSetClientOnly_f( void ) -{ - IN_TouchSetClientOnly( Q_atoi( Cmd_Argv( 1 ) ) ); -} - -void Touch_RemoveButton( touchbuttonlist_t *list, const char *name ) -{ - touchbutton2_t *button; - - IN_TouchEditClear(); - - while( ( button = IN_TouchFindFirst( &touch.list_user, name ) ) ) - { - if( button->prev ) - button->prev->next = button->next; - else - list->first = button->next; - if( button->next ) - button->next->prev = button->prev; - else - list->last = button->prev; - Mem_Free( button ); - } - -} - -void IN_TouchRemoveButton( const char *name ) -{ - Touch_RemoveButton( &touch.list_user, name ); -} - -void IN_TouchRemoveButton_f( void ) -{ - IN_TouchRemoveButton( Cmd_Argv( 1 ) ); -} - -void IN_TouchRemoveAll_f( void ) -{ - IN_TouchEditClear(); - while( touch.list_user.first ) - { - touchbutton2_t *remove = touch.list_user.first; - touch.list_user.first = touch.list_user.first->next; - Mem_Free ( remove ); - } - touch.list_user.last = NULL; -} - -void IN_TouchSetColor( touchbuttonlist_t *list, const char *name, byte *color ) -{ - touchbutton2_t *button; - for( button = list->first; button; button = button->next ) - { - if( ( Q_strstr( name, "*" ) && Q_stricmpext( name, button->name ) ) || !Q_strncmp( name, button->name, 32 ) ) - MakeRGBA( button->color, color[0], color[1], color[2], color[3] ); - } -} - -void IN_TouchSetTexture( touchbuttonlist_t *list, const char *name, const char *texture ) -{ - touchbutton2_t *button = IN_TouchFindButton( list, name ); - if( !button ) - return; - button->texture = -1; // mark for texture load - Q_strncpy( button->texturefile, texture, sizeof( button->texturefile ) ); -} - -void IN_TouchSetCommand( touchbuttonlist_t *list, const char *name, const char *command ) -{ - touchbutton2_t *button = IN_TouchFindButton( list, name ); - - if( !button ) - return; - - if( !Q_strcmp( command, "_look" ) ) - button->type = touch_look; - if( !Q_strcmp( command, "_move" ) ) - button->type = touch_move; - if( !Q_strcmp( command, "_joy" ) ) - button->type = touch_joy; - if( !Q_strcmp( command, "_dpad" ) ) - button->type = touch_dpad; - - Q_strncpy( button->command, command, sizeof( button->command ) ); -} - -void IN_TouchHideButtons( const char *name, qboolean hide ) -{ - touchbutton2_t *button; - - for( button = touch.list_user.first; button; button = button->next) - { - if( ( Q_strstr( name, "*" ) && Q_stricmpext( name, button->name ) ) || !Q_strncmp( name, button->name, 32 ) ) - { - if( hide ) - button->flags |= TOUCH_FL_HIDE; - else - button->flags &= ~TOUCH_FL_HIDE; - } - } - -} -void IN_TouchHide_f( void ) -{ - IN_TouchHideButtons( Cmd_Argv( 1 ), true ); -} - -void IN_TouchShow_f( void ) -{ - IN_TouchHideButtons( Cmd_Argv( 1 ), false ); -} - -void IN_TouchFadeButtons( touchbuttonlist_t *list, const char *name, float speed, float end, float start ) -{ - touchbutton2_t *button; - for( button = list->first; button; button = button->next) - { - if( ( Q_strstr( name, "*" ) && Q_stricmpext( name, button->name ) ) || !Q_strncmp( name, button->name, 32 ) ) - { - if( start >= 0 ) - button->fade = start; - button->fadespeed = speed; - button->fadeend = end; - } - } -} -void IN_TouchFade_f( void ) -{ - float start = -1; - if( Cmd_Argc() < 4 ) - return; - if( Cmd_Argc() > 4 ) - start = Q_atof( Cmd_Argv( 4 ) ); - IN_TouchFadeButtons( &touch.list_user, Cmd_Argv( 1 ), Q_atof( Cmd_Argv( 2 )), Q_atof( Cmd_Argv( 3 )), start ); -} - -void IN_TouchSetColor_f( void ) -{ - rgba_t color; - if( Cmd_Argc() == 6 ) - { - MakeRGBA( color, Q_atoi( Cmd_Argv(2) ), Q_atoi( Cmd_Argv(3) ), Q_atoi( Cmd_Argv(4) ), Q_atoi( Cmd_Argv(5) ) ); - IN_TouchSetColor( &touch.list_user, Cmd_Argv(1), color ); - return; - } - Msg( S_USAGE "touch_setcolor \n" ); -} - -void IN_TouchSetTexture_f( void ) -{ - if( Cmd_Argc() == 3 ) - { - IN_TouchSetTexture( &touch.list_user, Cmd_Argv( 1 ), Cmd_Argv( 2 ) ); - return; - } - Msg( S_USAGE "touch_settexture \n" ); -} - -void IN_TouchSetFlags_f( void ) -{ - if( Cmd_Argc() == 3 ) - { - touchbutton2_t *button = IN_TouchFindButton( &touch.list_user, Cmd_Argv( 1 ) ); - if( button ) - button->flags = Q_atoi( Cmd_Argv( 2 ) ); - return; - } - Msg( S_USAGE "touch_setflags \n" ); -} - -void IN_TouchSetCommand_f( void ) -{ - if( Cmd_Argc() == 3 ) - { - IN_TouchSetCommand( &touch.list_user, Cmd_Argv( 1 ), Cmd_Argv( 2 ) ); - return; - } - Msg( S_USAGE "touch_command \n" ); -} -void IN_TouchReloadConfig_f( void ) -{ - Cbuf_AddText( va("exec %s\n", touch_config_file->string ) ); -} - -touchbutton2_t *IN_TouchAddButton( touchbuttonlist_t *list, const char *name, const char *texture, const char *command, float x1, float y1, float x2, float y2, byte *color ) -{ - touchbutton2_t *button = Mem_Malloc( touch.mempool, sizeof( touchbutton2_t ) ); - button->texture = -1; - Q_strncpy( button->texturefile, texture, sizeof( button->texturefile ) ); - Q_strncpy( button->name, name, 32 ); - Touch_RemoveButton( list, name ); //replace if exist - button->x1 = x1; - button->y1 = y1; - button->x2 = x2; - button->y2 = y2; - MakeRGBA( button->color, color[0], color[1], color[2], color[3] ); - button->command[0] = 0; - button->flags = 0; - button->fade = 1; - - // check keywords - if( !Q_strcmp( command, "_look" ) ) - button->type = touch_look; - if( !Q_strcmp( command, "_move" ) ) - button->type = touch_move; - if( !Q_strcmp( command, "_joy" ) ) - button->type = touch_joy; - if( !Q_strcmp( command, "_dpad" ) ) - button->type = touch_dpad; - - Q_strncpy( button->command, command, sizeof( button->command ) ); - button->finger = -1; - button->next = NULL; - button->prev = list->last; - if( list->last ) - list->last->next = button; - list->last = button; - - if( !list->first ) - list->first = button; - - return button; -} - -void IN_TouchAddClientButton( const char *name, const char *texture, const char *command, float x1, float y1, float x2, float y2, byte *color, int round, float aspect, int flags ) -{ - touchbutton2_t *button; - - if( !touch.initialized ) - return; - if( round ) - IN_TouchCheckCoords( &x1, &y1, &x2, &y2 ); - if( round == round_aspect ) - { - y2 = y1 + ( x2 - x1 ) * (SCR_W/SCR_H) * aspect; - } - button = IN_TouchAddButton( &touch.list_user, name, texture, command, x1, y1, x2, y2, color ); - button->flags |= flags | TOUCH_FL_CLIENT | TOUCH_FL_NOEDIT; - button->aspect = aspect; -} - -void IN_TouchLoadDefaults_f( void ) -{ - int i; - for( i = 0; i < g_LastDefaultButton; i++ ) - { - touchbutton2_t *button; - float x1 = g_DefaultButtons[i].x1, - y1 = g_DefaultButtons[i].y1, - x2 = g_DefaultButtons[i].x2, - y2 = g_DefaultButtons[i].y2; - - IN_TouchCheckCoords( &x1, &y1, &x2, &y2 ); - - if( g_DefaultButtons[i].aspect && g_DefaultButtons[i].round == round_aspect ) - { - if( g_DefaultButtons[i].texturefile[0] == '#' ) - y2 = y1 + ( (float)clgame.scrInfo.iCharHeight / (float)clgame.scrInfo.iHeight ) * g_DefaultButtons[i].aspect + touch.swidth*2/SCR_H; - else - y2 = y1 + ( x2 - x1 ) * (SCR_W/SCR_H) * g_DefaultButtons[i].aspect; - } - - IN_TouchCheckCoords( &x1, &y1, &x2, &y2 ); - button = IN_TouchAddButton( &touch.list_user, g_DefaultButtons[i].name, g_DefaultButtons[i].texturefile, g_DefaultButtons[i].command, x1, y1, x2, y2, g_DefaultButtons[i].color ); - button->flags |= g_DefaultButtons[i].flags; - button->aspect = g_DefaultButtons[i].aspect; - } -} - - -// Add default button from client -void IN_TouchAddDefaultButton( const char *name, const char *texturefile, const char *command, float x1, float y1, float x2, float y2, byte *color, int round, float aspect, int flags ) -{ - if( g_LastDefaultButton >= 255 ) - return; - Q_strncpy( g_DefaultButtons[g_LastDefaultButton].name, name, 32 ); - Q_strncpy( g_DefaultButtons[g_LastDefaultButton].texturefile, texturefile, 256 ); - Q_strncpy( g_DefaultButtons[g_LastDefaultButton].command, command, 256 ); - g_DefaultButtons[g_LastDefaultButton].x1 = x1; - g_DefaultButtons[g_LastDefaultButton].y1 = y1; - g_DefaultButtons[g_LastDefaultButton].x2 = x2; - g_DefaultButtons[g_LastDefaultButton].y2 = y2; - MakeRGBA( g_DefaultButtons[g_LastDefaultButton].color, color[0], color[1], color[2], color[3] ); - g_DefaultButtons[g_LastDefaultButton].round = round; - g_DefaultButtons[g_LastDefaultButton].aspect = aspect; - g_DefaultButtons[g_LastDefaultButton].flags = flags; - g_LastDefaultButton++; -} - -// Client may remove all default buttons from engine -void IN_TouchResetDefaultButtons( void ) -{ - g_LastDefaultButton = 0; -} -void IN_TouchAddButton_f( void ) -{ - rgba_t color; - int argc = Cmd_Argc( ); - - if( argc >= 12 ) - { - touchbutton2_t *button; - MakeRGBA( color, Q_atoi( Cmd_Argv(8) ), Q_atoi( Cmd_Argv(9) ), - Q_atoi( Cmd_Argv(10) ), Q_atoi( Cmd_Argv(11) ) ); - button = IN_TouchAddButton( &touch.list_user, Cmd_Argv(1), Cmd_Argv(2), Cmd_Argv(3), - Q_atof( Cmd_Argv(4) ), Q_atof( Cmd_Argv(5) ), - Q_atof( Cmd_Argv(6) ), Q_atof( Cmd_Argv(7) ) , - color ); - if( argc >= 13 ) - button->flags = Q_atoi( Cmd_Argv(12) ); - if( argc >= 14 ) - { - // Recalculate button coordinates aspect ratio - // This is feature for distributed configs - float aspect = Q_atof( Cmd_Argv(13) ); - if( aspect ) - { - if( B(texturefile)[0] != '#' ) - B(y2) = B(y1) + ( B(x2) - B(x1) ) * (SCR_W/SCR_H) * aspect; - B(aspect) = aspect; - } - } - - return; - } - if( argc == 8 ) - { - MakeRGBA( color, 255, 255, 255, 255 ); - IN_TouchAddButton( &touch.list_user, Cmd_Argv(1), Cmd_Argv(2), Cmd_Argv(3), - Q_atof( Cmd_Argv(4) ), Q_atof( Cmd_Argv(5) ), - Q_atof( Cmd_Argv(6) ), Q_atof( Cmd_Argv(7) ), - color ); - return; - } - if( argc == 4 ) - { - MakeRGBA( color, 255, 255, 255, 255 ); - IN_TouchAddButton( &touch.list_user, Cmd_Argv(1), Cmd_Argv(2), Cmd_Argv(3), 0.4, 0.4, 0.6, 0.6, color ); - return; - } - Msg( S_USAGE "touch_addbutton [ [ r g b a ] ]\n" ); -} - -void IN_TouchEnableEdit_f( void ) -{ - if( touch.state == state_none ) - touch.state = state_edit; - touch.resize_finger = touch.move_finger = touch.look_finger = -1; - touch.move = NULL; - touch.configchanged = true; -} - -void IN_TouchDisableEdit_f( void ) -{ - touch.state = state_none; - if( touch.edit ) - touch.edit->finger = -1; - if( touch.selection ) - touch.selection->finger = -1; - touch.edit = touch.selection = NULL; - touch.resize_finger = touch.move_finger = touch.look_finger = -1; -} - -void IN_TouchDeleteProfile_f( void ) -{ - if( Cmd_Argc() != 2 ) - { - Msg( S_USAGE "touch_deleteprofile \n" ); - return; - } - - // delete profile - FS_Delete( va( "touch_profiles/%s.cfg", Cmd_Argv( 1 ))); -} - - -void IN_TouchInit( void ) -{ - rgba_t color; - if( touch.initialized ) - return; - touch.mempool = Mem_AllocPool( "Touch" ); - //touch.first = touch.last = NULL; - Con_Reportf( "IN_TouchInit()\n"); - touch.move_finger = touch.resize_finger = touch.look_finger = -1; - touch.state = state_none; - touch.showbuttons = true; - touch.clientonly = false; - touch.precision = false; - MakeRGBA( touch.scolor, 255, 255, 255, 255 ); - touch.swidth = 1; - g_LastDefaultButton = 0; - - // fill default buttons list - MakeRGBA( color, 255, 255, 255, 255 ); - IN_TouchAddDefaultButton( "look", "", "_look", 0.500000, 0.000000, 1.000000, 1, color, 0, 0, 0 ); - IN_TouchAddDefaultButton( "move", "", "_move", 0.000000, 0.000000, 0.500000, 1, color, 0, 0, 0 ); - IN_TouchAddDefaultButton( "invnext", "touch_default/next_weap.tga", "invnext", 0.000000, 0.530200, 0.120000, 0.757428, color, 2, 1, 0 ); - IN_TouchAddDefaultButton( "invprev", "touch_default/prev_weap.tga", "invprev", 0.000000, 0.075743, 0.120000, 0.302971, color, 2, 1, 0 ); - IN_TouchAddDefaultButton( "use", "touch_default/use.tga", "+use", 0.880000, 0.454457, 1.000000, 0.681685, color, 2, 1, 0 ); - IN_TouchAddDefaultButton( "jump", "touch_default/jump.tga", "+jump", 0.880000, 0.227228, 1.000000, 0.454457, color, 2, 1, 0 ); - IN_TouchAddDefaultButton( "attack", "touch_default/shoot.tga", "+attack", 0.760000, 0.530200, 0.880000, 0.757428, color, 2, 1, 0 ); - IN_TouchAddDefaultButton( "attack2", "touch_default/shoot_alt.tga", "+attack2", 0.760000, 0.302971, 0.880000, 0.530200, color, 2, 1, 0 ); - IN_TouchAddDefaultButton( "loadquick", "touch_default/load.tga", "loadquick", 0.760000, 0.000000, 0.840000, 0.151486, color, 2, 1, 16 ); - IN_TouchAddDefaultButton( "savequick", "touch_default/save.tga", "savequick", 0.840000, 0.000000, 0.920000, 0.151486, color, 2, 1, 16 ); - IN_TouchAddDefaultButton( "messagemode", "touch_default/keyboard.tga", "messagemode", 0.840000, 0.000000, 0.920000, 0.151486, color, 2, 1, 8 ); - IN_TouchAddDefaultButton( "reload", "touch_default/reload.tga", "+reload", 0.000000, 0.302971, 0.120000, 0.530200, color, 2, 1, 0 ); - IN_TouchAddDefaultButton( "flashlight", "touch_default/flash_light_filled.tga", "impulse 100", 0.920000, 0.000000, 1.000000, 0.151486, color, 2, 1, 0 ); - IN_TouchAddDefaultButton( "scores", "touch_default/map.tga", "+showscores", 0.760000, 0.000000, 0.840000, 0.151486, color, 2, 1, 8 ); - IN_TouchAddDefaultButton( "show_numbers", "touch_default/show_weapons.tga", "exec touch_default/numbers.cfg", 0.440000, 0.833171, 0.520000, 0.984656, color, 2, 1, 0 ); - IN_TouchAddDefaultButton( "duck", "touch_default/crouch.tga", "+duck", 0.880000, 0.757428, 1.000000, 0.984656, color, 2, 1, 0 ); - IN_TouchAddDefaultButton( "tduck", "touch_default/tduck.tga", ";+duck", 0.560000, 0.833171, 0.620000, 0.946785, color, 2, 1, 0 ); - IN_TouchAddDefaultButton( "edit", "touch_default/settings.tga", "touch_enableedit", 0.420000, 0.000000, 0.500000, 0.151486, color, 2, 1, 32 ); - IN_TouchAddDefaultButton( "menu", "touch_default/menu.tga", "escape", 0.000000, 0.833171, 0.080000, 0.984656, color, 2, 1, 0 ); - - - Cmd_AddCommand( "touch_addbutton", IN_TouchAddButton_f, "add native touch button" ); - Cmd_AddCommand( "touch_removebutton", IN_TouchRemoveButton_f, "remove native touch button" ); - Cmd_AddCommand( "touch_enableedit", IN_TouchEnableEdit_f, "enable button editing mode" ); - Cmd_AddCommand( "touch_disableedit", IN_TouchDisableEdit_f, "disable button editing mode" ); - Cmd_AddCommand( "touch_settexture", IN_TouchSetTexture_f, "change button texture" ); - Cmd_AddCommand( "touch_setcolor", IN_TouchSetColor_f, "change button color" ); - Cmd_AddCommand( "touch_setcommand", IN_TouchSetCommand_f, "change button command" ); - Cmd_AddCommand( "touch_setflags", IN_TouchSetFlags_f, "change button flags (be careful)" ); - Cmd_AddCommand( "touch_show", IN_TouchShow_f, "show button" ); - Cmd_AddCommand( "touch_hide", IN_TouchHide_f, "hide button" ); - Cmd_AddCommand( "touch_list", IN_TouchListButtons_f, "list buttons" ); - Cmd_AddCommand( "touch_removeall", IN_TouchRemoveAll_f, "remove all buttons" ); - Cmd_AddCommand( "touch_loaddefaults", IN_TouchLoadDefaults_f, "generate config from defaults" ); - Cmd_AddCommand( "touch_roundall", IN_TouchRoundAll_f, "round all buttons coordinates to grid" ); - Cmd_AddCommand( "touch_exportconfig", IN_TouchExportConfig_f, "export config keeping aspect ratio" ); - Cmd_AddCommand( "touch_set_stroke", IN_TouchStroke_f, "set global stroke width and color" ); - Cmd_AddCommand( "touch_setclientonly", IN_TouchSetClientOnly_f, "when 1, only client buttons are shown" ); - Cmd_AddCommand( "touch_reloadconfig", IN_TouchReloadConfig_f, "load config, not saving changes" ); - Cmd_AddCommand( "touch_writeconfig", IN_TouchWriteConfig, "save current config" ); - Cmd_AddCommand( "touch_deleteprofile", IN_TouchDeleteProfile_f, "delete profile by name" ); - Cmd_AddCommand( "touch_generate_code", IN_TouchGenetateCode_f, "create code sample for mobility API" ); - Cmd_AddCommand( "touch_fade", IN_TouchFade_f, "create code sample for mobility API" ); - - // not saved, just runtime state for scripting - touch_in_menu = Cvar_Get( "touch_in_menu", "0", 0, "draw touch in menu (for internal use only)" ); - - // sensitivity configuration - touch_forwardzone = Cvar_Get( "touch_forwardzone", "0.06", 0, "forward touch zone" ); - touch_sidezone = Cvar_Get( "touch_sidezone", "0.06", 0, "side touch zone" ); - touch_pitch = Cvar_Get( "touch_pitch", "90", 0, "touch pitch sensitivity" ); - touch_yaw = Cvar_Get( "touch_yaw", "120", 0, "touch yaw sensitivity" ); - touch_nonlinear_look = Cvar_Get( "touch_nonlinear_look", "0", 0, "enable nonlinear touch look" ); - touch_pow_factor = Cvar_Get( "touch_pow_factor", "1.0", 0, "set > 1 to enable" ); - touch_pow_mult = Cvar_Get( "touch_pow_mult", "300.0", 0, "power multiplier, usually 200-1000" ); - touch_exp_mult = Cvar_Get( "touch_exp_mult", "0", 0, "exponent multiplier, usually 20-200, 0 to disable" ); - - // touch.cfg - touch_grid_count = Cvar_Get( "touch_grid_count", "50", 0, "touch grid count" ); - touch_grid_enable = Cvar_Get( "touch_grid_enable", "1", 0, "enable touch grid" ); - touch_config_file = Cvar_Get( "touch_config_file", "touch.cfg", FCVAR_ARCHIVE, "current touch profile file" ); - touch_precise_amount = Cvar_Get( "touch_precise_amount", "0.5", 0, "sensitivity multiplier for precise-look" ); - touch_highlight_r = Cvar_Get( "touch_highlight_r", "1.0", 0, "highlight r color" ); - touch_highlight_g = Cvar_Get( "touch_highlight_g", "1.0", 0, "highlight g color" ); - touch_highlight_b = Cvar_Get( "touch_highlight_b", "1.0", 0, "highlight b color" ); - touch_highlight_a = Cvar_Get( "touch_highlight_a", "1.0", 0, "highlight alpha" ); - touch_dpad_radius = Cvar_Get( "touch_dpad_radius", "1.0", 0, "dpad radius multiplier" ); - touch_joy_radius = Cvar_Get( "touch_joy_radius", "1.0", 0, "joy radius multiplier" ); - touch_move_indicator = Cvar_Get( "touch_move_indicator", "0.0", 0, "indicate move events (0 to disable)" ); - touch_joy_texture = Cvar_Get( "touch_joy_texture", "touch_default/joy.tga", 0, "texture for move indicator"); - - // input devices cvar - touch_enable = Cvar_Get( "touch_enable", DEFAULT_TOUCH_ENABLE, FCVAR_ARCHIVE, "enable touch controls" ); - touch.initialized = true; -} - -// must be called after executing config.cfg -void IN_TouchInitConfig( void ) -{ - if( !touch.initialized ) - return; - - CL_GetScreenInfo( NULL ); //HACK: update hud screen parameters like iHeight - if( FS_FileExists( touch_config_file->string, true ) ) - Cbuf_AddText( va( "exec \"%s\"\n", touch_config_file->string ) ); - else IN_TouchLoadDefaults_f( ); - touch.closetexture = GL_LoadTexture( "touch_default/edit_close.tga", NULL, 0, TF_NOMIPMAP ); - touch.hidetexture = GL_LoadTexture( "touch_default/edit_hide.tga", NULL, 0, TF_NOMIPMAP ); - touch.showtexture = GL_LoadTexture( "touch_default/edit_show.tga", NULL, 0, TF_NOMIPMAP ); - touch.resettexture = GL_LoadTexture( "touch_default/edit_reset.tga", NULL, 0, TF_NOMIPMAP ); - touch.joytexture = GL_LoadTexture( touch_joy_texture->string, NULL, 0, TF_NOMIPMAP ); - touch.configchanged = false; -} -qboolean IN_TouchIsVisible( touchbutton2_t *button ) -{ - if( !(button->flags & TOUCH_FL_CLIENT) && touch.clientonly ) - return false; // skip nonclient buttons in clientonly mode - - if( touch.state >= state_edit ) - return true; //!!! Draw when editor is open - - if( button->flags & TOUCH_FL_HIDE ) - return false; // skip hidden - - if( button->flags & TOUCH_FL_SP && CL_GetMaxClients() != 1 ) - return false; // skip singleplayer(load, save) buttons in multiplayer - - if( button->flags & TOUCH_FL_MP && CL_GetMaxClients() == 1 ) - return false; // skip multiplayer buttons in singleplayer - - return true; - /* - return ( !touch.clientonly || ( button->flags & TOUCH_FL_CLIENT) ) && - ( - ( touch.state >= state_edit ) - ||( !( button->flags & TOUCH_FL_HIDE ) - && ( !(button->flags & TOUCH_FL_SP) || ( CL_GetMaxClients() == 1 ) ) - && ( !(button->flags & TOUCH_FL_MP) || ( CL_GetMaxClients() != 1 ) ) ) - ); - */ -} - -void Touch_DrawTexture ( float x1, float y1, float x2, float y2, int texture, byte r, byte g, byte b, byte a ) -{ - if( x1 >= x2 ) - return; - - if( y1 >= y2 ) - return; - - pglColor4ub( r, g, b, a ); - R_DrawStretchPic( TO_SCRN_X(x1), - TO_SCRN_Y(y1), - TO_SCRN_X(x2 - x1), - TO_SCRN_Y(y2 - y1), - 0, 0, 1, 1, texture ); -} - -#if defined(_MSC_VER) && (_MSC_VER < 1700) -static __inline int round(float f) -{ - return (int)(f + 0.5); - -} -#endif - -#define GRID_COUNT_X (touch_grid_count->value) -#define GRID_COUNT_Y (touch_grid_count->value * SCR_H / SCR_W) -#define GRID_X (1.0/GRID_COUNT_X) -#define GRID_Y (SCR_W/SCR_H/GRID_COUNT_X) -#define GRID_ROUND_X(x) ((float)round( x * GRID_COUNT_X ) / GRID_COUNT_X) -#define GRID_ROUND_Y(x) ((float)round( x * GRID_COUNT_Y ) / GRID_COUNT_Y) - -static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 ) -{ - /// TODO: grid check here - if( *x2 - *x1 < GRID_X * 2 ) - *x2 = *x1 + GRID_X * 2; - if( *y2 - *y1 < GRID_Y * 2) - *y2 = *y1 + GRID_Y * 2; - if( *x1 < 0 ) - *x2 -= *x1, *x1 = 0; - if( *y1 < 0 ) - *y2 -= *y1, *y1 = 0; - if( *y2 > 1 ) - *y1 -= *y2 - 1, *y2 = 1; - if( *x2 > 1 ) - *x1 -= *x2 - 1, *x2 = 1; - if ( touch_grid_enable->value ) - { - *x1 = GRID_ROUND_X( *x1 ); - *x2 = GRID_ROUND_X( *x2 ); - *y1 = GRID_ROUND_Y( *y1 ); - *y2 = GRID_ROUND_Y( *y2 ); - } -} - -float Touch_DrawCharacter( float x, float y, int number, float size ) -{ - float s1, s2, t1, t2, width, height; - int w, h; - wrect_t *prc; - if( !cls.creditsFont.valid ) - return 0; - - number &= 255; - number = Con_UtfProcessChar( number ); - - - R_GetTextureParms( &w, &h, cls.creditsFont.hFontTexture ); - prc = &cls.creditsFont.fontRc[number]; - - s1 = ((float)prc->left) / (float)w; - t1 = ((float)prc->top) / (float)h; - s2 = ((float)prc->right) / (float)w; - t2 = ((float)prc->bottom) / (float)h; - - width = ((float)( prc->right - prc->left )) / 1024.0f * size; - height = ((float)( prc->bottom - prc->top )) / 1024.0f * size; - - R_DrawStretchPic( TO_SCRN_X(x), TO_SCRN_Y(y), TO_SCRN_X(width), TO_SCRN_X(height), s1, t1, s2, t2, cls.creditsFont.hFontTexture ); - return width; -} - -float Touch_DrawText( float x1, float y1, float x2, float y2, const char *s, byte *color, float size ) -{ - float x = x1; - float maxy = y2; - float maxx; - if( x2 ) - maxx = x2 - cls.creditsFont.charWidths['M'] / 1024.0f * size; - else - maxx = 1; - - if( !cls.creditsFont.valid ) - return GRID_X * 2; - Con_UtfProcessChar( 0 ); - - GL_SetRenderMode( kRenderTransAdd ); - - // text is additive and alpha does not work - pglColor4ub( color[0] * ( (float)color[3] /255.0f ), color[1] * ( (float)color[3] /255.0f ), - color[2] * ( (float)color[3] /255.0f ), 255 ); - - while( *s ) - { - while( *s && ( *s != '\n' ) && ( *s != ';' ) && ( x1 < maxx ) ) - x1 += Touch_DrawCharacter( x1, y1, *s++, size ); - y1 += cls.creditsFont.charHeight / 1024.f * size / SCR_H * SCR_W; - - if( y1 >= maxy ) - break; - - if( *s == '\n' || *s == ';' ) - s++; - x1 = x; - } - GL_SetRenderMode( kRenderTransTexture ); - return x1; -} - -void Touch_DrawButtons( touchbuttonlist_t *list ) -{ - touchbutton2_t *button; - - for( button = list->first; button; button = button->next ) - { - if( IN_TouchIsVisible( button ) ) - { - rgba_t color; - MakeRGBA( color, B( color[0] ), B( color[1] ), B( color[2] ), B( color[3] ) ); - - if( B( fadespeed ) ) - { - button->fade += B( fadespeed ) * host.frametime; - button->fade = bound( 0, B(fade), 1 ); - if( ( B( fade ) == 0 ) || ( B(fade) == 1 ) ) - B( fadespeed ) = 0; - if( ( ( B( fade ) >= B( fadeend ) ) && ( B( fadespeed ) > 0 ) ) || - ( ( B( fade ) <= B( fadeend ) ) && ( B( fadespeed ) < 0 ) ) ) - B( fadespeed ) = 0, B( fade ) = B( fadeend ) ; - } - - if( ( B( finger ) != -1 ) && !( B( flags ) & TOUCH_FL_CLIENT ) ) - { - color[0] = bound( 0,(float) color[0] * touch_highlight_r->value, 255 ); - color[1] = bound( 0,(float) color[1] * touch_highlight_g->value, 255 ); - color[2] = bound( 0,(float) color[2] * touch_highlight_b->value, 255 ); - color[3] = bound( 0,(float) color[3] * touch_highlight_a->value, 255 ); - } - - color[3] *= B( fade ); - if( button->texturefile[0] == '#' ) - Touch_DrawText( touch.swidth/SCR_W + B(x1), touch.swidth/SCR_H + B(y1), B(x2), B(y2), button->texturefile + 1, color, B( aspect )?B(aspect):1 ); - else if( button->texturefile[0] ) - { - if( button->texture == -1 ) - { - button->texture = GL_LoadTexture( button->texturefile, NULL, 0, TF_NOMIPMAP ); - } - - if( B(flags) & TOUCH_FL_DRAW_ADDITIVE ) - GL_SetRenderMode( kRenderTransAdd ); - - Touch_DrawTexture( B(x1), B(y1), B(x2), B(y2), B(texture), color[0], color[1], color[2], color[3] ); - - GL_SetRenderMode( kRenderTransTexture ); - } - if( B(flags) & TOUCH_FL_STROKE ) - { - pglColor4ub( touch.scolor[0], touch.scolor[1], touch.scolor[2], touch.scolor[3] * B( fade ) ); - R_DrawStretchPic( TO_SCRN_X(B(x1)), - TO_SCRN_Y(B(y1)), - touch.swidth, - TO_SCRN_Y(B(y2)-B(y1)) - touch.swidth, - 0, 0, 1, 1, tr.whiteTexture ); - R_DrawStretchPic( TO_SCRN_X(B(x1)) + touch.swidth, - TO_SCRN_Y(B(y1)), - TO_SCRN_X(B(x2)-B(x1)) - touch.swidth, - touch.swidth, - 0, 0, 1, 1, tr.whiteTexture ); - R_DrawStretchPic( TO_SCRN_X(B(x2))-touch.swidth, - TO_SCRN_Y(B(y1)) + touch.swidth, - touch.swidth, - TO_SCRN_Y(B(y2)-B(y1)) - touch.swidth, - 0, 0, 1, 1, tr.whiteTexture ); - R_DrawStretchPic( TO_SCRN_X(B(x1)), - TO_SCRN_Y(B(y2))-touch.swidth, - TO_SCRN_X(B(x2)-B(x1)) - touch.swidth, - touch.swidth, - 0, 0, 1, 1, tr.whiteTexture ); - pglColor4ub( 255, 255, 255, 255 ); - } - } - if( touch.state >= state_edit ) - { - rgba_t color; - if( !( button->flags & TOUCH_FL_HIDE ) ) - Touch_DrawTexture( B(x1), B(y1), B(x2), B(y2), tr.whiteTexture, 255, 255, 0, 32 ); - else - Touch_DrawTexture( B(x1), B(y1), B(x2), B(y2), tr.whiteTexture, 128, 128, 128, 128 ); - MakeRGBA( color, 255, 255,127, 255 ); - Con_DrawString( TO_SCRN_X( B(x1) ), TO_SCRN_Y( B(y1) ), B(name), color ); - } - } - -} - -void IN_TouchDraw( void ) -{ - touchbutton2_t *button; - - if( !touch.initialized || (!touch_enable->value && !touch.clientonly) ) - return; - - if( cls.key_dest != key_game && touch_in_menu->value == 0.0f ) - return; - - GL_SetRenderMode( kRenderTransTexture ); - - if( touch.state >= state_edit && touch_grid_enable->value ) - { - float x; - if( touch_in_menu->value ) - Touch_DrawTexture( 0, 0, 1, 1, tr.whiteTexture, 32, 32, 32, 255 ); - else - Touch_DrawTexture( 0, 0, 1, 1, tr.whiteTexture, 0, 0, 0, 112 ); - pglColor4ub( 0, 224, 224, 112 ); - for ( x = 0; x < 1 ; x += GRID_X ) - R_DrawStretchPic( TO_SCRN_X(x), - 0, - 1, - TO_SCRN_Y(1), - 0, 0, 1, 1, tr.whiteTexture ); - for ( x = 0; x < 1 ; x += GRID_Y ) - R_DrawStretchPic( 0, - TO_SCRN_Y(x), - TO_SCRN_X(1), - 1, - 0, 0, 1, 1, tr.whiteTexture ); - } - - Touch_DrawButtons( &touch.list_user ); - - if( touch.state >= state_edit ) - { - rgba_t color; - MakeRGBA( color, 255, 255, 255, 255 ); - if( touch.edit ) - { - float x1 = touch.edit->x1, - y1 = touch.edit->y1, - x2 = touch.edit->x2, - y2 = touch.edit->y2; - IN_TouchCheckCoords( &x1, &y1, &x2, &y2 ); - Touch_DrawTexture( x1, y1, x2, y2, tr.whiteTexture, 0, 255, 0, 32 ); - } - Touch_DrawTexture( 0, 0, GRID_X, GRID_Y, tr.whiteTexture, 255, 255, 255, 64 ); - if( touch.selection ) - { - button = touch.selection; - Touch_DrawTexture( B(x1), B(y1), B(x2), B(y2), tr.whiteTexture, 255, 0, 0, 64 ); - if( touch.showbuttons ) - { - if( button->flags & TOUCH_FL_HIDE ) - { - Touch_DrawTexture( 0, GRID_Y * 8, GRID_X * 2, GRID_Y * 10, touch.showtexture, 255, 255, 255, 255 ); - Touch_DrawText( GRID_X * 2.5, GRID_Y * 8.5, 0, 0, "Show", color, 1.5 ); - } - else - { - Touch_DrawTexture( 0, GRID_Y * 8, GRID_X * 2, GRID_Y * 10, touch.hidetexture, 255, 255, 255, 255 ); - Touch_DrawText( GRID_X * 2.5, GRID_Y * 8.5, 0, 0, "Hide", color, 1.5 ); - } - } - Con_DrawString( 0, TO_SCRN_Y(GRID_Y * 11), "Selection:", color ); - Con_DrawString( Con_DrawString( 0, TO_SCRN_Y(GRID_Y*12), "Name: ", color ), - TO_SCRN_Y(GRID_Y*12), B(name), color ); - Con_DrawString( Con_DrawString( 0, TO_SCRN_Y(GRID_Y*13), "Texture: ", color ), - TO_SCRN_Y(GRID_Y*13), B(texturefile), color ); - Con_DrawString( Con_DrawString( 0, TO_SCRN_Y(GRID_Y*14), "Command: ", color ), - TO_SCRN_Y(GRID_Y*14), B(command), color ); - } - if( touch.showbuttons ) - { - // close - Touch_DrawTexture( 0, GRID_Y * 2, GRID_X * 2, GRID_Y * 4, touch.closetexture, 255, 255, 255, 255 ); - //Con_DrawString( TO_SCRN_X( GRID_X * 2.5 ), TO_SCRN_Y( GRID_Y * 2.5 ), "Close", color ); - Touch_DrawText( GRID_X * 2.5, GRID_Y * 2.5, 0, 0, "Close", color, 1.5 ); - // reset - Touch_DrawTexture( 0, GRID_Y * 5, GRID_X * 2, GRID_Y * 7, touch.resettexture, 255, 255, 255, 255 ); - //Con_DrawString( TO_SCRN_X( GRID_X * 2.5 ), TO_SCRN_Y( GRID_Y * 5.5 ), "Reset", color ); - Touch_DrawText( GRID_X * 2.5, GRID_Y * 5.5, 0, 0, "Reset", color, 1.5 ); - } - } - pglColor4ub( 255, 255, 255, 255 ); - if( ( touch.move_finger != -1 ) && touch.move && touch_move_indicator->value ) - { - float width; - float height; - if( FBitSet( touch_joy_texture->flags, FCVAR_CHANGED ) ) - { - ClearBits( touch_joy_texture->flags, FCVAR_CHANGED ); - touch.joytexture = GL_LoadTexture( touch_joy_texture->string, NULL, 0, TF_NOMIPMAP ); - } - if( touch.move->type == touch_move ) - { - width = touch_sidezone->value; - height = touch_forwardzone->value; - } - else - { - width = (touch.move->x2 - touch.move->x1)/2; - height = (touch.move->y2 - touch.move->y1)/2; - } - pglColor4ub( 255, 255, 255, 128 ); - R_DrawStretchPic( TO_SCRN_X( touch.move_start_x - GRID_X * touch_move_indicator->value ), - TO_SCRN_Y( touch.move_start_y - GRID_Y * touch_move_indicator->value ), - TO_SCRN_X( GRID_X * 2 * touch_move_indicator->value ), TO_SCRN_Y( GRID_Y * 2 * touch_move_indicator->value ), 0, 0, 1, 1, touch.joytexture ); - pglColor4ub( 255, 255, 255, 255 ); - R_DrawStretchPic( TO_SCRN_X( touch.move_start_x + touch.side * width - GRID_X * touch_move_indicator->value ), - TO_SCRN_Y( touch.move_start_y - touch.forward * height - GRID_Y * touch_move_indicator->value ), - TO_SCRN_X( GRID_X * 2 * touch_move_indicator->value ), TO_SCRN_Y( GRID_Y * 2 * touch_move_indicator->value ), 0, 0, 1, 1, touch.joytexture ); - - } - -} - -// clear move and selection state -void IN_TouchEditClear( void ) -{ - // Allow keep move/look fingers when doing touch_removeall - //touch.move_finger = touch.look_finger = -1; - if( touch.state < state_edit ) - return; - touch.state = state_edit; - if( touch.edit ) - touch.edit->finger = -1; - touch.resize_finger = -1; - touch.edit = NULL; - touch.selection = NULL; -} - -static void Touch_EditMove( touchEventType type, int fingerID, float x, float y, float dx, float dy ) -{ - if( touch.edit->finger == fingerID ) - { - if( type == event_up ) // shutdown button move - { - touchbutton2_t *button = touch.edit; - IN_TouchCheckCoords( &B(x1), &B(y1), &B(x2), &B(y2) ); - IN_TouchEditClear(); - if( button->type == touch_command ) - touch.selection = button; - } - if( type == event_motion ) // shutdown button move - { - touch.edit->y1 += dy; - touch.edit->y2 += dy; - touch.edit->x1 += dx; - touch.edit->x2 += dx; - } - } - else - { - if( type == event_down ) // enable resizing - { - if( touch.resize_finger == -1 ) - { - touch.resize_finger = fingerID; - } - } - if( type == event_up ) // disable resizing - { - if( touch.resize_finger == fingerID ) - { - touch.resize_finger = -1; - } - } - if( type == event_motion ) // perform resizing - { - if( touch.resize_finger == fingerID ) - { - touch.edit->y2 += dy; - touch.edit->x2 += dx; - } - } - } -} - -static void Touch_Motion( touchEventType type, int fingerID, float x, float y, float dx, float dy ) -{ - // walk - if( fingerID == touch.move_finger ) - { - // check bounds - if( touch_forwardzone->value <= 0 ) - Cvar_SetValue( "touch_forwardzone", 0.5 ); - if( touch_sidezone->value <= 0 ) - Cvar_SetValue( "touch_sidezone", 0.3 ); - - if( !touch.move || touch.move->type == touch_move ) - { - // move relative to touch start - touch.forward = ( touch.move_start_y - y ) / touch_forwardzone->value; - touch.side = ( x - touch.move_start_x ) / touch_sidezone->value; - } - else if( touch.move->type == touch_joy ) - { - // move relative to joy center - touch.forward = ( ( touch.move->y2 + touch.move->y1 ) - y * 2 ) / ( touch.move->y2 - touch.move->y1 ) * touch_joy_radius->value; - touch.side = ( x * 2 - ( touch.move->x2 + touch.move->x1 ) ) / ( touch.move->x2 - touch.move->x1 ) * touch_joy_radius->value; - } - else if( touch.move->type == touch_dpad ) - { - // like joy, but without acceleration. useful for bhop - touch.forward = round( ( (touch.move->y2 + touch.move->y1) - y * 2 ) / ( touch.move->y2 - touch.move->y1 ) * touch_dpad_radius->value ); - touch.side = round( ( x * 2 - (touch.move->x2 + touch.move->x1) ) / ( touch.move->x2 - touch.move->x1 ) * touch_dpad_radius->value ); - } - - touch.forward = bound( -1, touch.forward, 1 ); - touch.side = bound( -1, touch.side, 1 ); - } - - // process look - if( fingerID == touch.look_finger ) - { - if( touch.precision ) - dx *= touch_precise_amount->value, dy *= touch_precise_amount->value; - - if( touch_nonlinear_look->value ); - { - // save angle, modify only velocity - float dabs = sqrt( dx*dx+dy*dy ); - float dcos = dx/dabs; - float dsin = dy/dabs; - - if( touch_exp_mult->value > 1 ) - dabs = (exp(dabs*touch_exp_mult->value)-1)/touch_exp_mult->value; - if( touch_pow_mult->value > 1 && touch_pow_factor->value > 1 ) - dabs = pow(dabs*touch_pow_mult->value,touch_pow_factor->value)/touch_pow_mult->value; - - dx = dabs * dcos; - dy = dabs * dsin; - } - - // accumulate - touch.yaw -= dx * touch_yaw->value, touch.pitch += dy * touch_pitch->value; - } -} - - -static qboolean Touch_ButtonPress( touchbuttonlist_t *list, touchEventType type, int fingerID, float x, float y, float dx, float dy ) -{ - touchbutton2_t *button; - - // run from end(front) to start(back) - for( button = list->last; button; button = button->prev ) - { - if( type == event_down ) - { - if( ( x > button->x1 && - x < button->x2 ) && - ( y < button->y2 && - y > button->y1 ) ) - { - button->finger = fingerID; - - if( !IN_TouchIsVisible( button ) ) - continue; - - if( button->type == touch_command ) - { - char command[256]; - Q_snprintf( command, sizeof( command ), "%s\n", button->command ); - Cbuf_AddText( command ); - - if( B(flags) & TOUCH_FL_PRECISION ) - touch.precision = true; - } - if( button->type == touch_move || button->type == touch_joy || button->type == touch_dpad ) - { - if( touch.move_finger !=-1 ) - { - button->finger = touch.move_finger; - continue; - } - if( touch.look_finger == fingerID ) - { - touchbutton2_t *newbutton; - touch.move_finger = touch.look_finger = -1; - //touch.move_finger = button->finger = -1; - for( newbutton = list->first; newbutton; newbutton = newbutton->next ) - if( ( newbutton->type == touch_move ) || ( newbutton->type == touch_look ) ) newbutton->finger = -1; - Con_Reportf( "Touch: touch_move on look finger %d!\n", fingerID ); - continue; - } - touch.move_finger = fingerID; - touch.move = button; - if( touch.move->type == touch_move ) - { - touch.move_start_x = x; - touch.move_start_y = y; - } - else if( touch.move->type == touch_joy ) - { - touch.move_start_y = (touch.move->y2 + touch.move->y1) / 2; - touch.move_start_x = (touch.move->x2 + touch.move->x1) / 2; - touch.forward = ((touch.move->y2 + touch.move->y1) - y * 2) / (touch.move->y2 - touch.move->y1); - touch.side = (x * 2 - (touch.move->x2 + touch.move->x1)) / (touch.move->x2 - touch.move->x1); - } - else if( touch.move->type == touch_dpad ) - { - touch.move_start_y = (touch.move->y2 + touch.move->y1) / 2; - touch.move_start_x = (touch.move->x2 + touch.move->x1) / 2; - touch.forward = round(((touch.move->y2 + touch.move->y1) - y * 2) / (touch.move->y2 - touch.move->y1)); - touch.side = round((x * 2 - (touch.move->x2 + touch.move->x1)) / (touch.move->x2 - touch.move->x1)); - } - } - if( button->type == touch_look ) - { - if( touch.look_finger !=-1 ) - { - button->finger = touch.look_finger; - continue; - } - if( touch.move_finger == fingerID ) - { - touchbutton2_t *newbutton; - // This is an error, try recover - touch.move_finger = touch.look_finger = -1; - for( newbutton = list->first; newbutton; newbutton = newbutton->next ) - if( ( newbutton->type == touch_move ) || ( newbutton->type == touch_look ) ) newbutton->finger = -1; - Con_Reportf( "Touch: touch_look on move finger %d!\n", fingerID ); - continue; - } - touch.look_finger = fingerID; - } - } - } - if( type == event_up ) - { - if( fingerID == button->finger ) - { - button->finger = -1; - if( !IN_TouchIsVisible( button ) ) - continue; - - if( ( button->type == touch_command ) && ( button->command[0] == '+' ) ) - { - char command[256]; - Q_snprintf( command, sizeof( command ), "%s\n", button->command ); - command[0] = '-'; - Cbuf_AddText( command ); - if( B(flags) & TOUCH_FL_PRECISION ) - touch.precision = false; - } - if( button->type == touch_move || button->type == touch_joy || button->type == touch_dpad ) - { - touch.move_finger = -1; - touch.forward = touch.side = 0; - touch.move = NULL; - } - if( button->type == touch_look ) - { - touch.look_finger = -1; - } - } - } - } - - return false; -} - -static qboolean Touch_ButtonEdit( touchEventType type, int fingerID, float x, float y, float dx, float dy ) -{ - touchbutton2_t *button; - - // edit buttons are on y1 - if( type == event_down ) - { - if( (x < GRID_X) && (y < GRID_Y) ) - { - touch.showbuttons ^= true; - return true; - } - if( touch.showbuttons && ( x < GRID_X * 2 ) ) - { - if( ( y > GRID_Y * 2 ) && ( y < GRID_Y * 4 ) ) // close button - { - IN_TouchDisableEdit_f(); - if( touch_in_menu->value ) - { - Cvar_Set( "touch_in_menu", "0" ); - } - else - IN_TouchWriteConfig(); - return true; - } - if( ( y > GRID_Y * 5 ) && ( y < GRID_Y * 7 ) ) // reset button - { - IN_TouchReloadConfig_f(); - return true; - } - if( ( y > GRID_Y * 8 ) && ( y < GRID_Y * 10 ) && touch.selection ) // hide button - { - touch.selection->flags ^= TOUCH_FL_HIDE; - return true; - } - } - } - - // run from end(front) to start(back) - for( button = touch.list_user.last; button; button = button->prev ) - { - if( type == event_down ) - { - if( ( x > button->x1 && - x < button->x2 ) && - ( y < button->y2 && - y > button->y1 ) ) - { - button->finger = fingerID; - - // do not edit NOEDIT buttons - if( button->flags & TOUCH_FL_NOEDIT ) - continue; - - touch.edit = button; - touch.selection = NULL; - // Make button last to bring it up - if( ( button->next ) && ( button->type == touch_command ) ) - { - if( button->prev ) - button->prev->next = button->next; - else - touch.list_user.first = button->next; - - button->next->prev = button->prev; - touch.list_user.last->next = button; - button->prev = touch.list_user.last; - button->next = NULL; - touch.list_user.last = button; - } - touch.state = state_edit_move; - return true; - } - } - if( type == event_up ) - if( fingerID == button->finger ) - button->finger = -1; - } - - if( type == event_down ) - touch.selection = NULL; - - return false; -} - -static int Touch_ControlsEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy ) -{ - touchbutton2_t *button; - - if( touch.state == state_edit_move ) - { - Touch_EditMove( type, fingerID, x, y, dx, dy ); - return 1; - } - - if( touch.state == state_edit && Touch_ButtonEdit( type, fingerID, x, y, dx, dy ) ) - return true; - if( Touch_ButtonPress( &touch.list_user, type, fingerID, x, y, dx, dy ) ) - return true; - if( type == event_motion ) - Touch_Motion( type, fingerID, x, y, dx, dy ); - return true; -} - -int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy ) -{ - - // simulate menu mouse click - if( cls.key_dest != key_game && !touch_in_menu->value ) - { - touch.move_finger = touch.resize_finger = touch.look_finger = -1; - // Hack for keyboard, hope it help - if( cls.key_dest == key_console || cls.key_dest == key_message ) - { - Key_EnableTextInput( true, true ); - if( cls.key_dest == key_console ) - { - static float y1 = 0; - y1 += dy; - if( dy > 0.4 ) - Con_Bottom(); - if( y1 > 0.01 ) - { - Con_PageUp( 1 ); - y1 = 0; - } - if( y1 < -0.01 ) - { - Con_PageDown( 1 ); - y1 = 0; - } - } - - // exit of console area - if( type == event_down && x < 0.1f && y > 0.9f ) - Cbuf_AddText( "escape\n" ); - } - UI_MouseMove( TO_SCRN_X(x), TO_SCRN_Y(y) ); - //Con_Reportf( "touch %d %d\n", TO_SCRN_X(x), TO_SCRN_Y(y) ); - if( type == event_down ) - Key_Event( K_MOUSE1, true ); - if( type == event_up ) - Key_Event( K_MOUSE1, false ); - return 0; - } - - - if( VGui_IsActive() ) - { - VGui_MouseMove( TO_SCRN_X(x), TO_SCRN_Y(y) ); - - if( type != event_motion ) - VGui_KeyEvent( K_MOUSE1, type == event_down ? 1 : 0 ); - - // allow scoreboard scroll - if( host.mouse_visible && type == event_motion ) - return 0; - } - - if( !touch.initialized || (!touch_enable->value && !touch.clientonly) ) - { -#if 0 - if( type == event_down ) - Key_Event( K_MOUSE1, true ); - if( type == event_up ) - Key_Event( K_MOUSE1, false ); - Android_AddMove( dx * (float)glState.width, dy * glState.height ); -#endif - return 0; - } - - if( clgame.dllFuncs.pfnTouchEvent && clgame.dllFuncs.pfnTouchEvent( type, fingerID, x, y, dx, dy ) ) - return true; - - return Touch_ControlsEvent( type, fingerID, x, y, dx, dy ); -} - -void IN_TouchMove( float *forward, float *side, float *yaw, float *pitch ) -{ - *forward += touch.forward; - *side += touch.side; - *yaw += touch.yaw; - *pitch += touch.pitch; - touch.yaw = touch.pitch = 0; -} - -void IN_TouchKeyEvent( int key, int down ) -{ - int xi, yi; - float x, y; - - if( touch_enable->value ) - return; - - if( !touch.clientonly ) - return; - - Platform_GetMousePos( &xi, &yi ); - - x = xi/SCR_W; - y = yi/SCR_H; - - Touch_ControlsEvent( !down, key == K_MOUSE1?0:1, x, y, 0, 0 ); -} - -void IN_TouchShutdown( void ) -{ - if( !touch.initialized ) - return; - IN_TouchRemoveAll_f(); - Cmd_RemoveCommand( "touch_addbutton" ); - Cmd_RemoveCommand( "touch_removebutton" ); - Cmd_RemoveCommand( "touch_enableedit" ); - Cmd_RemoveCommand( "touch_disableedit" ); - Cmd_RemoveCommand( "touch_settexture" ); - Cmd_RemoveCommand( "touch_setcolor" ); - Cmd_RemoveCommand( "touch_setcommand" ); - Cmd_RemoveCommand( "touch_setflags" ); - Cmd_RemoveCommand( "touch_show" ); - Cmd_RemoveCommand( "touch_hide" ); - Cmd_RemoveCommand( "touch_list" ); - Cmd_RemoveCommand( "touch_removeall" ); - Cmd_RemoveCommand( "touch_loaddefaults" ); - Cmd_RemoveCommand( "touch_roundall" ); - Cmd_RemoveCommand( "touch_exportconfig" ); - Cmd_RemoveCommand( "touch_set_stroke" ); - Cmd_RemoveCommand( "touch_setclientonly" ); - Cmd_RemoveCommand( "touch_reloadconfig" ); - Cmd_RemoveCommand( "touch_writeconfig" ); - Cmd_RemoveCommand( "touch_generate_code" ); - - touch.initialized = false; - Mem_FreePool( &touch.mempool ); -} -#endif diff --git a/engine/client/input.c b/engine/client/input.c index d8ced306..80880f0d 100644 --- a/engine/client/input.c +++ b/engine/client/input.c @@ -17,7 +17,6 @@ GNU General Public License for more details. #include "input.h" #include "client.h" #include "vgui_draw.h" -#include "gl_local.h" #ifdef XASH_SDL #include @@ -143,7 +142,7 @@ void IN_ToggleClientMouse( int newstate, int oldstate ) { // reset mouse pos, so cancel effect in game #ifdef XASH_SDL - if( touch_enable->value ) + if( 0 ) // touch_enable->value ) { SDL_SetRelativeMouseMode( SDL_FALSE ); SDL_SetWindowGrab( host.hWnd, SDL_FALSE ); @@ -518,7 +517,7 @@ void IN_CollectInput( float *forward, float *side, float *pitch, float *yaw, qbo } Joy_FinalizeMove( forward, side, yaw, pitch ); - IN_TouchMove( forward, side, yaw, pitch ); + // IN_TouchMove( forward, side, yaw, pitch ); if( look_filter->value ) { @@ -551,15 +550,15 @@ void IN_EngineAppendMove( float frametime, usercmd_t *cmd, qboolean active ) if( active ) { - float sensitivity = ( (float)RI.fov_x / (float)90.0f ); + float sensitivity = ( (float)refState.fov_x / (float)90.0f ); IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized, m_enginemouse->value ); IN_JoyAppendMove( cmd, forward, side ); - RI.viewangles[YAW] += yaw * sensitivity; - RI.viewangles[PITCH] += pitch * sensitivity; - RI.viewangles[PITCH] = bound( -90, RI.viewangles[PITCH], 90 ); + refState.viewangles[YAW] += yaw * sensitivity; + refState.viewangles[PITCH] += pitch * sensitivity; + refState.viewangles[PITCH] = bound( -90, refState.viewangles[PITCH], 90 ); } } diff --git a/engine/client/mod_dbghulls.c b/engine/client/mod_dbghulls.c index edf27a31..aa5094c2 100644 --- a/engine/client/mod_dbghulls.c +++ b/engine/client/mod_dbghulls.c @@ -1,5 +1,5 @@ /* -mod_bmodel.c - loading & handling world and brushmodels +mod_dbghulls.c - loading & handling world and brushmodels Copyright (C) 2016 Uncle Mike This program is free software: you can redistribute it and/or modify @@ -12,12 +12,12 @@ 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 "mod_local.h" #include "mathlib.h" #include "world.h" -#include "gl_local.h" -#include "client.h" + #define MAX_CLIPNODE_DEPTH 256 // should never exceeds @@ -713,66 +713,3 @@ void Mod_ReleaseHullPolygons( void ) } world.num_hull_models = 0; } - -void R_DrawWorldHull( void ) -{ - hull_model_t *hull = &world.hull_models[0]; - winding_t *poly; - int i; - - if( FBitSet( r_showhull->flags, FCVAR_CHANGED )) - { - int val = bound( 0, (int)r_showhull->value, 3 ); - if( val ) Mod_CreatePolygonsForHull( val ); - ClearBits( r_showhull->flags, FCVAR_CHANGED ); - } - - if( !CVAR_TO_BOOL( r_showhull )) - return; - pglDisable( GL_TEXTURE_2D ); - - list_for_each_entry( poly, &hull->polys, chain ) - { - srand((unsigned int)poly); - pglColor3f( rand() % 256 / 255.0, rand() % 256 / 255.0, rand() % 256 / 255.0 ); - pglBegin( GL_POLYGON ); - for( i = 0; i < poly->numpoints; i++ ) - pglVertex3fv( poly->p[i] ); - pglEnd(); - } - pglEnable( GL_TEXTURE_2D ); -} - -void R_DrawModelHull( void ) -{ - hull_model_t *hull; - winding_t *poly; - int i; - - if( !CVAR_TO_BOOL( r_showhull )) - return; - - if( !RI.currentmodel || RI.currentmodel->name[0] != '*' ) - return; - - i = atoi( RI.currentmodel->name + 1 ); - if( i < 1 || i >= world.num_hull_models ) - return; - - hull = &world.hull_models[i]; - - pglPolygonOffset( 1.0f, 2.0 ); - pglEnable( GL_POLYGON_OFFSET_FILL ); - pglDisable( GL_TEXTURE_2D ); - list_for_each_entry( poly, &hull->polys, chain ) - { - srand((unsigned int)poly); - pglColor3f( rand() % 256 / 255.0, rand() % 256 / 255.0, rand() % 256 / 255.0 ); - pglBegin( GL_POLYGON ); - for( i = 0; i < poly->numpoints; i++ ) - pglVertex3fv( poly->p[i] ); - pglEnd(); - } - pglEnable( GL_TEXTURE_2D ); - pglDisable( GL_POLYGON_OFFSET_FILL ); -} diff --git a/engine/client/ref_common.c b/engine/client/ref_common.c new file mode 100644 index 00000000..9a54dc04 --- /dev/null +++ b/engine/client/ref_common.c @@ -0,0 +1,499 @@ +#include "common.h" +#include "client.h" +#include "library.h" +#include "cl_tent.h" +#include "platform/platform.h" +#include "vid_common.h" + +struct ref_state_s ref; +ref_globals_t refState; + +convar_t *gl_vsync; +convar_t *gl_showtextures; +convar_t *r_decals; +convar_t *r_adjust_fov; +convar_t *gl_wgl_msaa_samples; + +void R_GetTextureParms( int *w, int *h, int texnum ) +{ + if( w ) *w = REF_GET_PARM( PARM_TEX_WIDTH, texnum ); + if( h ) *h = REF_GET_PARM( PARM_TEX_HEIGHT, texnum ); +} + +/* +================ +GL_FreeImage + +Frees image by name +================ +*/ +void GL_FreeImage( const char *name ) +{ + int texnum; + + if(( texnum = ref.dllFuncs.GL_FindTexture( name )) != 0 ) + ref.dllFuncs.GL_FreeTexture( texnum ); +} + +static int pfnEngineGetParm( int parm, int arg ) +{ + return CL_RenderGetParm( parm, arg, false ); // prevent recursion +} + +static void pfnCbuf_SetOpenGLConfigHack( qboolean set ) +{ + host.apply_opengl_config = set; +} + +static world_static_t *pfnGetWorld( void ) +{ + return &world; +} + +static void pfnStudioEvent( const mstudioevent_t *event, const cl_entity_t *e ) +{ + clgame.dllFuncs.pfnStudioEvent( event, e ); +} + +static efrag_t* pfnGetEfragsFreeList( void ) +{ + return clgame.free_efrags; +} + +static void pfnSetEfragsFreeList( efrag_t *list ) +{ + clgame.free_efrags = list; +} + +static model_t *pfnGetDefaultSprite( enum ref_defaultsprite_e spr ) +{ + switch( spr ) + { + case REF_DOT_SPRITE: return cl_sprite_dot; + case REF_CHROME_SPRITE: return cl_sprite_shell; + default: Host_Error( "GetDefaultSprite: unknown sprite %d\n", spr ); + } + return NULL; +} + +static void *pfnMod_Extradata( int type, model_t *m ) +{ + switch( type ) + { + case mod_alias: return Mod_AliasExtradata( m ); + case mod_studio: return Mod_StudioExtradata( m ); + case mod_sprite: // fallthrough + case mod_brush: return NULL; + default: Host_Error( "Mod_Extradata: unknown type %d\n", type ); + } + return NULL; +} + +static model_t *pfnMod_GetCurrentLoadingModel( void ) +{ + return loadmodel; +} + +static void pfnMod_SetCurrentLoadingModel( model_t *m ) +{ + loadmodel = m; +} + +static void pfnGetPredictedOrigin( vec3_t v ) +{ + VectorCopy( cl.simorg, v ); +} + +static color24 *pfnCL_GetPaletteColor(int color) // clgame.palette[color] +{ + return &clgame.palette[color]; +} + +static void pfnCL_GetScreenInfo( int *width, int *height ) // clgame.scrInfo, ptrs may be NULL +{ + if( width ) *width = clgame.scrInfo.iWidth; + if( height ) *height = clgame.scrInfo.iHeight; +} + +static void pfnSetLocalLightLevel( int level ) +{ + cl.local.light_level = level; +} + +/* +=============== +pfnPlayerInfo + +=============== +*/ +static player_info_t *pfnPlayerInfo( int index ) +{ + if( index == -1 ) // special index for menu + return &gameui.playerinfo; + + if( index < 0 || index > cl.maxclients ) + return NULL; + + return &cl.players[index]; +} + +/* +=============== +pfnGetPlayerState + +=============== +*/ +static entity_state_t *R_StudioGetPlayerState( int index ) +{ + if( index < 0 || index >= cl.maxclients ) + return NULL; + + return &cl.frames[cl.parsecountmod].playerstate[index]; +} + +static int pfnGetStudioModelInterface( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio ) +{ + return clgame.dllFuncs.pfnGetStudioModelInterface( version, ppinterface, pstudio ); +} + +static byte *pfnImage_GetPool( void ) +{ + return host.imagepool; +} + +static const bpc_desc_t *pfnImage_GetPFDesc( int idx ) +{ + return &PFDesc[idx]; +} + +static void pfnDrawNormalTriangles( void ) +{ + clgame.dllFuncs.pfnDrawNormalTriangles(); +} + +static void pfnDrawTransparentTriangles( void ) +{ + clgame.dllFuncs.pfnDrawTransparentTriangles(); +} + +static screenfade_t *pfnRefGetScreenFade( void ) +{ + return &clgame.fade; +} + +static ref_api_t gEngfuncs = +{ + pfnEngineGetParm, + + Cvar_Get, + Cvar_FindVarExt, + Cvar_VariableValue, + Cvar_VariableString, + Cvar_SetValue, + Cvar_Set, + Cvar_RegisterVariable, + Cvar_FullSet, + + Cmd_AddRefCommand, + Cmd_RemoveCommand, + Cmd_Argc, + Cmd_Argv, + Cmd_Args, + + Cbuf_AddText, + Cbuf_InsertText, + Cbuf_Execute, + pfnCbuf_SetOpenGLConfigHack, + + Con_Printf, + Con_DPrintf, + Con_Reportf, + + Con_NPrintf, + Con_NXPrintf, + CL_CenterPrint, + Con_DrawStringLen, + Con_DrawString, + CL_DrawCenterPrint, + + CL_GetLocalPlayer, + CL_GetViewModel, + CL_GetEntityByIndex, + R_BeamGetEntity, + CL_GetWaterEntity, + CL_AddVisibleEntity, + + Mod_SampleSizeForFace, + Mod_BoxVisible, + pfnGetWorld, + Mod_PointInLeaf, + Mod_CreatePolygonsForHull, + + R_StudioSlerpBones, + R_StudioCalcBoneQuaternion, + R_StudioCalcBonePosition, + R_StudioGetAnim, + pfnStudioEvent, + + CL_DrawEFX, + CL_ThinkParticle, + R_FreeDeadParticles, + CL_AllocParticleFast, + CL_AllocElight, + pfnGetDefaultSprite, + R_StoreEfrags, + + Mod_ForName, + pfnMod_Extradata, + CL_ModelHandle, + pfnMod_GetCurrentLoadingModel, + pfnMod_SetCurrentLoadingModel, + + CL_GetRemapInfoForEntity, + CL_AllocRemapInfo, + CL_FreeRemapInfo, + CL_UpdateRemapInfo, + + CL_ExtraUpdate, + COM_HashKey, + Host_Error, + CL_FxBlend, + COM_SetRandomSeed, + COM_RandomFloat, + COM_RandomLong, + pfnRefGetScreenFade, + CL_TextMessageGet, + pfnGetPredictedOrigin, + pfnCL_GetPaletteColor, + pfnCL_GetScreenInfo, + pfnSetLocalLightLevel, + Sys_CheckParm, + + pfnPlayerInfo, + R_StudioGetPlayerState, + Mod_CacheCheck, + Mod_LoadCacheFile, + Mod_Calloc, + pfnGetStudioModelInterface, + + _Mem_AllocPool, + _Mem_FreePool, + _Mem_Alloc, + _Mem_Realloc, + _Mem_Free, + + COM_LoadLibrary, + COM_FreeLibrary, + COM_GetProcAddress, + + FS_LoadFile, + COM_ParseFile, + FS_FileExists, + FS_AllowDirectPaths, + + R_Init_Video, + R_Free_Video, + + GL_SetAttribute, + GL_GetAttribute, + GL_GetProcAddress, + GL_SwapBuffers, + + BuildGammaTable, + LightToTexGamma, + + CL_GetLightStyle, + CL_GetDynamicLight, + CL_GetEntityLight, + R_FatPVS, + GL_GetOverviewParms, + Sys_DoubleTime, + + pfnGetPhysent, + pfnTraceSurface, + PM_TraceLine, + CL_VisTraceLine, + CL_TraceLine, + pfnGetMoveVars, + + Image_AddCmdFlags, + Image_SetForceFlags, + Image_ClearForceFlags, + Image_CustomPalette, + Image_Process, + FS_LoadImage, + FS_SaveImage, + FS_CopyImage, + FS_FreeImage, + Image_SetMDLPointer, + pfnImage_GetPool, + pfnImage_GetPFDesc, + + pfnDrawNormalTriangles, + pfnDrawTransparentTriangles, + &clgame.drawFuncs +}; + +static void R_UnloadProgs( void ) +{ + if( !ref.hInstance ) return; + + // deinitialize renderer + ref.dllFuncs.R_Shutdown(); + + Cvar_FullSet( "host_refloaded", "0", FCVAR_READ_ONLY ); + + COM_FreeLibrary( ref.hInstance ); + ref.hInstance = NULL; + + memset( &refState, 0, sizeof( refState )); + memset( &ref.dllFuncs, 0, sizeof( ref.dllFuncs )); + + Cvar_Unlink( FCVAR_RENDERINFO | FCVAR_GLCONFIG ); + Cmd_Unlink( CMD_REFDLL ); +} + +static void CL_FillTriAPIFromRef( triangleapi_t *dst, const ref_interface_t *src ) +{ + dst->version = TRI_API_VERSION; + dst->Begin = src->Begin; + dst->RenderMode = TriRenderMode; + dst->End = src->End; + dst->Color4f = TriColor4f; + dst->Color4ub = TriColor4ub; + dst->TexCoord2f = src->TexCoord2f; + dst->Vertex3f = src->Vertex3f; + dst->Vertex3fv = src->Vertex3fv; + dst->Brightness = TriBrightness; + dst->CullFace = TriCullFace; + dst->SpriteTexture = TriSpriteTexture; + dst->WorldToScreen = TriWorldToScreen; + dst->Fog = src->Fog; + dst->ScreenToWorld = src->ScreenToWorld; + dst->GetMatrix = src->GetMatrix; + dst->BoxInPVS = TriBoxInPVS; + dst->LightAtPoint = TriLightAtPoint; + dst->Color4fRendermode = TriColor4fRendermode; + dst->FogParams = src->FogParams; +} + +static qboolean R_LoadProgs( const char *name ) +{ + extern triangleapi_t gTriApi; + static ref_api_t gpEngfuncs; + REFAPI GetRefAPI; // single export + + if( ref.hInstance ) R_UnloadProgs(); + +#ifdef XASH_INTERNAL_GAMELIBS + if( !(ref.hInstance = COM_LoadLibrary( name, false, true ) )) + { + return false; + } +#else + if( !(ref.hInstance = COM_LoadLibrary( name, false, true ) )) + { + FS_AllowDirectPaths( true ); + if( !(ref.hInstance = COM_LoadLibrary( name, false, true ) )) + { + FS_AllowDirectPaths( false ); + return false; + } + + } +#endif + + FS_AllowDirectPaths( false ); + + if( ( GetRefAPI = (REFAPI)COM_GetProcAddress( ref.hInstance, "GetRefAPI" )) == NULL ) + { + COM_FreeLibrary( ref.hInstance ); + Con_Reportf( "R_LoadProgs: can't init renderer API\n" ); + ref.hInstance = NULL; + return false; + } + + // make local copy of engfuncs to prevent overwrite it with user dll + memcpy( &gpEngfuncs, &gEngfuncs, sizeof( gpEngfuncs )); + + if( !GetRefAPI( REF_API_VERSION, &ref.dllFuncs, &gpEngfuncs, &refState )) + { + COM_FreeLibrary( ref.hInstance ); + Con_Reportf( "R_LoadProgs: can't init renderer API: wrong version\n" ); + ref.hInstance = NULL; + return false; + } + + refState.developer = host_developer.value; + + if( !ref.dllFuncs.R_Init( ) ) + { + COM_FreeLibrary( ref.hInstance ); + Con_Reportf( "R_LoadProgs: can't init renderer!\n" ); //, ref.dllFuncs.R_GetInitError() ); + ref.hInstance = NULL; + return false; + } + + Cvar_FullSet( "host_refloaded", "1", FCVAR_READ_ONLY ); + ref.initialized = true; + + // initialize TriAPI callbacks + CL_FillTriAPIFromRef( &gTriApi, &ref.dllFuncs ); + + return true; +} + +void R_Shutdown( void ) +{ + int i; + model_t *mod; + + // release SpriteTextures + for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ ) + { + if( !mod->name[0] ) continue; + Mod_FreeModel( mod ); + } + memset( clgame.sprites, 0, sizeof( clgame.sprites )); + + // correctly free all models before render unload + // change this if need add online render changing + Mod_FreeAll(); + R_UnloadProgs(); + ref.initialized = false; +} + +qboolean R_Init( void ) +{ + char refdll[64]; + + refdll[0] = 0; + + if( !Sys_GetParmFromCmdLine( "-ref", refdll ) ) + { + Q_snprintf( refdll, sizeof( refdll ), "%s%s.%s", +#ifdef OS_LIB_PREFIX + OS_LIB_PREFIX, +#else + "", +#endif + DEFAULT_RENDERER, OS_LIB_EXT ); + } + + 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" ); + 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" ); + gl_wgl_msaa_samples = Cvar_Get( "gl_wgl_msaa_samples", "0", FCVAR_GLCONFIG, "samples number for multisample anti-aliasing" ); + + if( !R_LoadProgs( refdll )) + { + R_Shutdown(); + Host_Error( "Can't initialize %s renderer!\n", refdll ); + return false; + } + + SCR_Init(); + + return true; +} diff --git a/engine/client/ref_common.h b/engine/client/ref_common.h new file mode 100644 index 00000000..7fa594d9 --- /dev/null +++ b/engine/client/ref_common.h @@ -0,0 +1,47 @@ +/* +ref_common.h - Xash3D render dll API +Copyright (C) 2019 a1batross + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ +#pragma once +#if !defined REF_COMMON_H && !defined REF_DLL +#define REF_COMMON_H + +#include "ref_api.h" + +#define RP_LOCALCLIENT( e ) ((e) != NULL && (e)->index == ( cl.playernum + 1 ) && e->player ) + +struct ref_state_s +{ + qboolean initialized; + + HINSTANCE hInstance; + ref_interface_t dllFuncs; +}; + +extern struct ref_state_s ref; +extern ref_globals_t refState; + +// handy API wrappers +void R_GetTextureParms( int *w, int *h, int texnum ); +#define REF_GET_PARM( parm, arg ) ref.dllFuncs.RefGetParm( (parm), (arg) ) +#define GL_LoadTextureInternal( name, pic, flags ) ref.dllFuncs.GL_LoadTextureFromBuffer( name, pic, flags, false ) +#define GL_UpdateTextureInternal( name, pic, flags ) ref.dllFuncs.GL_LoadTextureFromBuffer( name, pic, flags, true ) + +// common engine and renderer cvars +extern convar_t *r_decals; +extern convar_t *r_adjust_fov; + +qboolean R_Init( void ); +void R_Shutdown( void ); + +#endif // REF_COMMON_H diff --git a/engine/client/s_main.c b/engine/client/s_main.c index e8345344..32fd884c 100644 --- a/engine/client/s_main.c +++ b/engine/client/s_main.c @@ -17,7 +17,6 @@ GNU General Public License for more details. #include "sound.h" #include "client.h" #include "con_nprint.h" -#include "gl_local.h" #include "pm_local.h" #include "platform/platform.h" @@ -926,7 +925,7 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv // and we didn't find it (it's not playing), go ahead and start it up } - if( !pos ) pos = RI.vieworg; + if( !pos ) pos = refState.vieworg; if( chan == CHAN_STREAM ) SetBits( flags, SND_STOP_LOOPING ); diff --git a/engine/client/s_vox.c b/engine/client/s_vox.c index 5955e344..7e16b7de 100644 --- a/engine/client/s_vox.c +++ b/engine/client/s_vox.c @@ -606,7 +606,7 @@ void VOX_ReadSentenceFile( const char *psentenceFileName ) { char c, *pch, *pFileData; char *pchlast, *pSentenceData; - size_t fileSize; + fs_offset_t fileSize; // load file pFileData = (char *)FS_LoadFile( psentenceFileName, &fileSize, false ); diff --git a/engine/client/vgui/vgui_draw.c b/engine/client/vgui/vgui_draw.c index 0a2eae48..a5916d94 100644 --- a/engine/client/vgui/vgui_draw.c +++ b/engine/client/vgui/vgui_draw.c @@ -18,40 +18,22 @@ GNU General Public License for more details. #include #include "common.h" #include "client.h" -#include "gl_local.h" #include "vgui_draw.h" #include "vgui_api.h" #include "library.h" #include "keydefs.h" -#include "gl_local.h" +#include "ref_common.h" #ifdef XASH_SDL #include static SDL_Cursor* s_pDefaultCursor[20]; #endif #include "platform/platform.h" -int g_textures[VGUI_MAX_TEXTURES]; -int g_textureId = 0; -int g_iBoundTexture; static enum VGUI_KeyCode s_pVirtualKeyTrans[256]; static enum VGUI_DefaultCursor s_currentCursor; static HINSTANCE s_pVGuiSupport; // vgui_support library static convar_t *vgui_utf8 = NULL; -void VGUI_DrawInit( void ); -void VGUI_DrawShutdown( void ); -void VGUI_SetupDrawingText( int *pColor ); -void VGUI_SetupDrawingRect( int *pColor ); -void VGUI_SetupDrawingImage( int *pColor ); -void VGUI_BindTexture( int id ); -void VGUI_EnableTexture( qboolean enable ); -void VGUI_CreateTexture( int id, int width, int height ); -void VGUI_UploadTexture( int id, const char *buffer, int width, int height ); -void VGUI_UploadTextureBlock( int id, int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight ); -void VGUI_DrawQuad( const vpoint_t *ul, const vpoint_t *lr ); -void VGUI_GetTextureSizes( int *width, int *height ); -int VGUI_GenerateTexture( void ); - // Helper functions for vgui backend /*void VGUI_HideCursor( void ) @@ -78,8 +60,8 @@ qboolean GAME_EXPORT VGUI_IsInGame( void ) void GAME_EXPORT VGUI_GetMousePos( int *_x, int *_y ) { - float xscale = (float)glState.width / (float)clgame.scrInfo.iWidth; - float yscale = (float)glState.height / (float)clgame.scrInfo.iHeight; + float xscale = (float)refState.width / (float)clgame.scrInfo.iWidth; + float yscale = (float)refState.height / (float)clgame.scrInfo.iHeight; int x, y; Platform_GetMousePos( &x, &y ); @@ -176,19 +158,19 @@ int GAME_EXPORT VGUI_UtfProcessChar( int in ) vguiapi_t vgui = { false, // Not initialized yet - VGUI_DrawInit, - VGUI_DrawShutdown, - VGUI_SetupDrawingText, - VGUI_SetupDrawingRect, - VGUI_SetupDrawingImage, - VGUI_BindTexture, - VGUI_EnableTexture, - VGUI_CreateTexture, - VGUI_UploadTexture, - VGUI_UploadTextureBlock, - VGUI_DrawQuad, - VGUI_GetTextureSizes, - VGUI_GenerateTexture, + NULL, // VGUI_DrawInit, + NULL, // VGUI_DrawShutdown, + NULL, // VGUI_SetupDrawingText, + NULL, // VGUI_SetupDrawingRect, + NULL, // VGUI_SetupDrawingImage, + NULL, // VGUI_BindTexture, + NULL, // VGUI_EnableTexture, + NULL, // VGUI_CreateTexture, + NULL, // VGUI_UploadTexture, + NULL, // VGUI_UploadTextureBlock, + NULL, // VGUI_DrawQuad, + NULL, // VGUI_GetTextureSizes, + NULL, // VGUI_GenerateTexture, VGUI_EngineMalloc, /* VGUI_ShowCursor, VGUI_HideCursor,*/ @@ -212,6 +194,23 @@ qboolean VGui_IsActive( void ) return vgui.initialized; } +void VGui_FillAPIFromRef( vguiapi_t *to, const ref_interface_t *from ) +{ + to->DrawInit = from->VGUI_DrawInit; + to->DrawShutdown = from->VGUI_DrawShutdown; + to->SetupDrawingText = from->VGUI_SetupDrawingText; + to->SetupDrawingRect = from->VGUI_SetupDrawingRect; + to->SetupDrawingImage = from->VGUI_SetupDrawingImage; + to->BindTexture = from->VGUI_BindTexture; + to->EnableTexture = from->VGUI_EnableTexture; + to->CreateTexture = from->VGUI_CreateTexture; + to->UploadTexture = from->VGUI_UploadTexture; + to->UploadTextureBlock = from->VGUI_UploadTextureBlock; + to->DrawQuad = from->VGUI_DrawQuad; + to->GetTextureSizes = from->VGUI_GetTextureSizes; + to->GenerateTexture = from->VGUI_GenerateTexture; +} + /* ================ VGui_Startup @@ -236,6 +235,8 @@ void VGui_Startup( int width, int height ) { vgui_utf8 = Cvar_Get( "vgui_utf8", "0", FCVAR_ARCHIVE, "enable utf-8 support for vgui text" ); + VGui_FillAPIFromRef( &vgui, &ref.dllFuncs ); + #ifdef XASH_INTERNAL_GAMELIBS s_pVGuiSupport = COM_LoadLibrary( "client", false, false ); @@ -521,237 +522,12 @@ void VGui_KeyEvent( int key, int down ) void VGui_MouseMove( int x, int y ) { - float xscale = (float)glState.width / (float)clgame.scrInfo.iWidth; - float yscale = (float)glState.height / (float)clgame.scrInfo.iHeight; + float xscale = (float)refState.width / (float)clgame.scrInfo.iWidth; + float yscale = (float)refState.height / (float)clgame.scrInfo.iHeight; if( vgui.initialized ) vgui.MouseMove( x / xscale, y / yscale ); } -/* -================ -VGUI_DrawInit - -Startup VGUI backend -================ -*/ -void GAME_EXPORT VGUI_DrawInit( void ) -{ - memset( g_textures, 0, sizeof( g_textures )); - g_textureId = g_iBoundTexture = 0; -} - -/* -================ -VGUI_DrawShutdown - -Release all textures -================ -*/ -void GAME_EXPORT VGUI_DrawShutdown( void ) -{ - int i; - - for( i = 1; i < g_textureId; i++ ) - { - GL_FreeTexture( g_textures[i] ); - } -} - -/* -================ -VGUI_GenerateTexture - -generate unique texture number -================ -*/ -int GAME_EXPORT VGUI_GenerateTexture( void ) -{ - if( ++g_textureId >= VGUI_MAX_TEXTURES ) - Sys_Error( "VGUI_GenerateTexture: VGUI_MAX_TEXTURES limit exceeded\n" ); - return g_textureId; -} - -/* -================ -VGUI_UploadTexture - -Upload texture into video memory -================ -*/ -void GAME_EXPORT VGUI_UploadTexture( int id, const char *buffer, int width, int height ) -{ - rgbdata_t r_image; - char texName[32]; - - if( id <= 0 || id >= VGUI_MAX_TEXTURES ) - { - Con_DPrintf( S_ERROR "VGUI_UploadTexture: bad texture %i. Ignored\n", id ); - return; - } - - Q_snprintf( texName, sizeof( texName ), "*vgui%i", id ); - memset( &r_image, 0, sizeof( r_image )); - - r_image.width = width; - r_image.height = height; - r_image.type = PF_RGBA_32; - r_image.size = r_image.width * r_image.height * 4; - r_image.flags = IMAGE_HAS_COLOR|IMAGE_HAS_ALPHA; - r_image.buffer = (byte *)buffer; - - g_textures[id] = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE ); -} - -/* -================ -VGUI_CreateTexture - -Create empty rgba texture and upload them into video memory -================ -*/ -void GAME_EXPORT VGUI_CreateTexture( int id, int width, int height ) -{ - rgbdata_t r_image; - char texName[32]; - - if( id <= 0 || id >= VGUI_MAX_TEXTURES ) - { - Con_Reportf( S_ERROR "VGUI_CreateTexture: bad texture %i. Ignored\n", id ); - return; - } - - Q_snprintf( texName, sizeof( texName ), "*vgui%i", id ); - memset( &r_image, 0, sizeof( r_image )); - - r_image.width = width; - r_image.height = height; - r_image.type = PF_RGBA_32; - r_image.size = r_image.width * r_image.height * 4; - r_image.flags = IMAGE_HAS_ALPHA; - r_image.buffer = NULL; - - g_textures[id] = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE|TF_NEAREST ); - g_iBoundTexture = id; -} - -void GAME_EXPORT VGUI_UploadTextureBlock( int id, int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight ) -{ - if( id <= 0 || id >= VGUI_MAX_TEXTURES || g_textures[id] == 0 || g_textures[id] == tr.whiteTexture ) - { - Con_Reportf( S_ERROR "VGUI_UploadTextureBlock: bad texture %i. Ignored\n", id ); - return; - } - - pglTexSubImage2D( GL_TEXTURE_2D, 0, drawX, drawY, blockWidth, blockHeight, GL_RGBA, GL_UNSIGNED_BYTE, rgba ); - g_iBoundTexture = id; -} - -void GAME_EXPORT VGUI_SetupDrawingRect( int *pColor ) -{ - pglEnable( GL_BLEND ); - pglDisable( GL_ALPHA_TEST ); - pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - pglColor4ub( pColor[0], pColor[1], pColor[2], 255 - pColor[3] ); -} - -void GAME_EXPORT VGUI_SetupDrawingText( int *pColor ) -{ - pglEnable( GL_BLEND ); - pglEnable( GL_ALPHA_TEST ); - pglAlphaFunc( GL_GREATER, 0.0f ); - pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - pglColor4ub( pColor[0], pColor[1], pColor[2], 255 - pColor[3] ); -} - -void GAME_EXPORT VGUI_SetupDrawingImage( int *pColor ) -{ - pglEnable( GL_BLEND ); - pglEnable( GL_ALPHA_TEST ); - pglAlphaFunc( GL_GREATER, 0.0f ); - pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - pglColor4ub( pColor[0], pColor[1], pColor[2], 255 - pColor[3] ); -} - -void GAME_EXPORT VGUI_BindTexture( int id ) -{ - if( id > 0 && id < VGUI_MAX_TEXTURES && g_textures[id] ) - { - GL_Bind( XASH_TEXTURE0, g_textures[id] ); - g_iBoundTexture = id; - } - else - { - // NOTE: same as bogus index 2700 in GoldSrc - id = g_iBoundTexture = 1; - GL_Bind( XASH_TEXTURE0, g_textures[id] ); - } -} - -/* -================ -VGUI_GetTextureSizes - -returns wide and tall for currently binded texture -================ -*/ -void GAME_EXPORT VGUI_GetTextureSizes( int *width, int *height ) -{ - gl_texture_t *glt; - int texnum; - - if( g_iBoundTexture ) - texnum = g_textures[g_iBoundTexture]; - else texnum = tr.defaultTexture; - - glt = R_GetTexture( texnum ); - if( width ) *width = glt->srcWidth; - if( height ) *height = glt->srcHeight; -} - -/* -================ -VGUI_EnableTexture - -disable texturemode for fill rectangle -================ -*/ -void GAME_EXPORT VGUI_EnableTexture( qboolean enable ) -{ - if( enable ) pglEnable( GL_TEXTURE_2D ); - else pglDisable( GL_TEXTURE_2D ); -} - -/* -================ -VGUI_DrawQuad - -generic method to fill rectangle -================ -*/ -void GAME_EXPORT VGUI_DrawQuad( const vpoint_t *ul, const vpoint_t *lr ) -{ - float xscale = glState.width / (float)clgame.scrInfo.iWidth; - float yscale = glState.height / (float)clgame.scrInfo.iHeight; - - ASSERT( ul != NULL && lr != NULL ); - - pglBegin( GL_QUADS ); - pglTexCoord2f( ul->coord[0], ul->coord[1] ); - pglVertex2f( ul->point[0] * xscale, ul->point[1] * yscale ); - - pglTexCoord2f( lr->coord[0], ul->coord[1] ); - pglVertex2f( lr->point[0] * xscale, ul->point[1] * yscale ); - - pglTexCoord2f( lr->coord[0], lr->coord[1] ); - pglVertex2f( lr->point[0] * xscale, lr->point[1] * yscale ); - - pglTexCoord2f( ul->coord[0], lr->coord[1] ); - pglVertex2f( ul->point[0] * xscale, lr->point[1] * yscale ); - pglEnd(); -} - void VGui_Paint() { if(vgui.initialized) diff --git a/engine/client/vgui/vgui_draw.h b/engine/client/vgui/vgui_draw.h index 3b252b47..439df91a 100644 --- a/engine/client/vgui/vgui_draw.h +++ b/engine/client/vgui/vgui_draw.h @@ -22,8 +22,6 @@ extern "C" { #include "port.h" -#define VGUI_MAX_TEXTURES 2048 // a half of total textures count - // // vgui_draw.c // diff --git a/engine/client/vid_common.c b/engine/client/vid_common.c index b7a6188d..6bc654fb 100644 --- a/engine/client/vid_common.c +++ b/engine/client/vid_common.c @@ -15,197 +15,22 @@ GNU General Public License for more details. #include "common.h" #include "client.h" -#include "gl_local.h" #include "mod_local.h" #include "input.h" #include "vid_common.h" #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_showtextures; -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; - -ref_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; -} - +convar_t *window_xpos; +convar_t *window_ypos; /* ================= VID_StartupGamma @@ -228,8 +53,8 @@ void VID_InitDefaultResolution( void ) { // we need to have something valid here // until video subsystem initialized - glState.width = 640; - glState.height = 480; + refState.width = 640; + refState.height = 480; } /* @@ -239,8 +64,8 @@ R_SaveVideoMode */ void R_SaveVideoMode( int w, int h ) { - glState.width = w; - glState.height = h; + refState.width = w; + refState.height = h; host.window_center_x = w / 2; host.window_center_y = h / 2; @@ -250,8 +75,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; + refState.wideScreen = true; + else refState.wideScreen = false; } /* @@ -282,7 +107,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 ); } @@ -301,96 +126,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; @@ -426,98 +161,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_adjust_fov = Cvar_Get( "r_adjust_fov", "1", FCVAR_ARCHIVE, "making FOV adjustment for wide-screens" ); - 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 = Cvar_Get( "r_decals", "4096", FCVAR_ARCHIVE, "sets the maximum number of 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 = Cvar_Get( "gl_vsync", "0", FCVAR_ARCHIVE, "enable vertical syncronization" ); - 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 = Cvar_Get( "r_showtextures", "0", FCVAR_CHEAT, "show all uploaded textures" ); - 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 = Cvar_Get( "fullscreen", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable fullscreen mode" ); - vid_displayfrequency = Cvar_Get ( "vid_displayfrequency", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "fullscreen refresh rate" ); - 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(); -} - -/* -================= -GL_RemoveCommands -================= -*/ -void GL_RemoveCommands( void ) -{ - Cmd_RemoveCommand( "r_info"); -} - static void SetWidthAndHeightFromCommandLine() { int width, height; @@ -548,171 +191,29 @@ static void SetFullscreenModeFromCommandLine( ) #endif } - -/* -=============== -R_CheckVBO - -register VBO cvars and get default value -=============== -*/ -static void R_CheckVBO( void ) +void VID_Init() { - const char *def = "1"; - const char *dlightmode = "1"; - int flags = FCVAR_ARCHIVE; - qboolean disable = false; + // 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" ); - // some bad GLES1 implementations breaks dlights completely - if( glConfig.max_texture_units < 3 ) - disable = true; + 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" ); -#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; + vid_gamma = Cvar_Get( "gamma", "2.5", FCVAR_ARCHIVE, "gamma amount" ); + vid_brightness = Cvar_Get( "brightness", "0.0", FCVAR_ARCHIVE, "brightness factor" ); + 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" ); + vid_highdpi = Cvar_Get( "vid_highdpi", "1", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable High-DPI mode" ); - // 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(); + // 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" ); // 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 ); + R_Init(); // init renderer } diff --git a/engine/client/vid_common.h b/engine/client/vid_common.h index 3047f584..6cc4802a 100644 --- a/engine/client/vid_common.h +++ b/engine/client/vid_common.h @@ -2,9 +2,6 @@ #ifndef VID_COMMON #define VID_COMMON -#define FCONTEXT_CORE_PROFILE BIT( 0 ) -#define FCONTEXT_DEBUG_ARB BIT( 1 ) - typedef struct vidmode_s { const char *desc; @@ -12,27 +9,35 @@ typedef struct vidmode_s int height; } vidmode_t; -// minimal recommended resolution -#define VID_MIN_WIDTH 640 -#define VID_MIN_HEIGHT 480 -// -// vid_common.c -// -qboolean VID_SetMode( void ); -#define GL_CheckForErrors() GL_CheckForErrors_( __FILE__, __LINE__ ) -void GL_CheckForErrors_( const char *filename, const int fileline ); -const char *GL_ErrorString( int err ); -void GL_UpdateSwapInterval( void ); -qboolean GL_Support( int r_ext ); -void VID_CheckChanges( void ); -int GL_MaxTextureUnits( void ); -qboolean R_Init( void ); -void R_Shutdown( void ); -const char *VID_GetModeString( int vid_mode ); +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; + +extern glwstate_t glw_state; + +#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 ); -void GL_CheckExtension( const char *name, const dllfunc_t *funcs, const char *cvarname, int r_ext ); -void GL_SetExtension( int r_ext, int enable ); +void GL_SwapBuffers(); #endif // VID_COMMON diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 1f29a5f0..15e54092 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -711,6 +711,16 @@ int Cmd_AddGameUICommand( const char *cmd_name, xcommand_t function ) return Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, "gameui command", CMD_GAMEUIDLL ); } +/* +============ +Cmd_AddRefCommand +============ +*/ +int Cmd_AddRefCommand( const char *cmd_name, xcommand_t function, const char *description ) +{ + return Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, description, CMD_REFDLL ); +} + /* ============ Cmd_RemoveCommand diff --git a/engine/common/common.c b/engine/common/common.c index 2c09cf18..603335cf 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -428,173 +428,9 @@ uint LZSS_Decompress( const byte *pInput, byte *pOutput ) return totalBytes; } -/* -============ -COM_FileBase -Extracts the base name of a file (no path, no extension, assumes '/' as path separator) -============ -*/ -void COM_FileBase( const char *in, char *out ) -{ - int len, start, end; - len = Q_strlen( in ); - if( !len ) return; - - // scan backward for '.' - end = len - 1; - while( end && in[end] != '.' && in[end] != '/' && in[end] != '\\' ) - end--; - - if( in[end] != '.' ) - end = len-1; // no '.', copy to end - else end--; // found ',', copy to left of '.' - - // scan backward for '/' - start = len - 1; - - while( start >= 0 && in[start] != '/' && in[start] != '\\' ) - start--; - - if( start < 0 || ( in[start] != '/' && in[start] != '\\' )) - start = 0; - else start++; - - // length of new sting - len = end - start + 1; - - // Copy partial string - Q_strncpy( out, &in[start], len + 1 ); - out[len] = 0; -} - -/* -============ -COM_FileExtension -============ -*/ -const char *COM_FileExtension( const char *in ) -{ - const char *separator, *backslash, *colon, *dot; - - separator = Q_strrchr( in, '/' ); - backslash = Q_strrchr( in, '\\' ); - - if( !separator || separator < backslash ) - separator = backslash; - - colon = Q_strrchr( in, ':' ); - - if( !separator || separator < colon ) - separator = colon; - - dot = Q_strrchr( in, '.' ); - - if( dot == NULL || ( separator && ( dot < separator ))) - return ""; - - return dot + 1; -} - -/* -============ -COM_FileWithoutPath -============ -*/ -const char *COM_FileWithoutPath( const char *in ) -{ - const char *separator, *backslash, *colon; - - separator = Q_strrchr( in, '/' ); - backslash = Q_strrchr( in, '\\' ); - - if( !separator || separator < backslash ) - separator = backslash; - - colon = Q_strrchr( in, ':' ); - - if( !separator || separator < colon ) - separator = colon; - - return separator ? separator + 1 : in; -} - -/* -============ -COM_ExtractFilePath -============ -*/ -void COM_ExtractFilePath( const char *path, char *dest ) -{ - const char *src = path + Q_strlen( path ) - 1; - - // back up until a \ or the start - while( src != path && !(*(src - 1) == '\\' || *(src - 1) == '/' )) - src--; - - if( src != path ) - { - memcpy( dest, path, src - path ); - dest[src - path - 1] = 0; // cutoff backslash - } - else Q_strcpy( dest, "" ); // file without path -} - -/* -============ -COM_StripExtension -============ -*/ -void COM_StripExtension( char *path ) -{ - size_t length; - - length = Q_strlen( path ) - 1; - while( length > 0 && path[length] != '.' ) - { - length--; - if( path[length] == '/' || path[length] == '\\' || path[length] == ':' ) - return; // no extension - } - - if( length ) path[length] = 0; -} - -/* -================== -COM_DefaultExtension -================== -*/ -void COM_DefaultExtension( char *path, const char *extension ) -{ - const char *src; - - // if path doesn't have a .EXT, append extension - // (extension should include the .) - src = path + Q_strlen( path ) - 1; - - while( *src != '/' && src != path ) - { - // it has an extension - if( *src == '.' ) return; - src--; - } - - Q_strcat( path, extension ); -} - -/* -================== -COM_ReplaceExtension -================== -*/ -void COM_ReplaceExtension( char *path, const char *extension ) -{ - COM_StripExtension( path ); - COM_DefaultExtension( path, extension ); -} /* ============== @@ -767,12 +603,14 @@ COM_CheckString ============= */ +#if 0 int COM_CheckString( const char *string ) { if( !string || !*string ) return 0; return 1; } +#endif /* ============= @@ -1323,6 +1161,19 @@ qboolean COM_IsSafeFileToDownload( const char *filename ) return true; } +char *_copystring( byte *mempool, const char *s, const char *filename, int fileline ) +{ + char *b; + + if( !s ) return NULL; + if( !mempool ) mempool = host.mempool; + + b = _Mem_Alloc( mempool, Q_strlen( s ) + 1, false, filename, fileline ); + Q_strcpy( b, s ); + + return b; +} + /* ====================== diff --git a/engine/common/common.h b/engine/common/common.h index 6a728b1b..44fddb84 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -47,16 +47,8 @@ XASH SPECIFIC - sort of hack that works only in Xash3D not in GoldSrc #ifndef _WIN32 #include // size_t - -#ifdef __i386__ -#define EXPORT __attribute__ ((visibility ("default"),force_align_arg_pointer)) -#else -#define EXPORT __attribute__ ((visibility ("default"))) -#endif #else #include // off_t - -#define EXPORT __declspec( dllexport ) #endif // configuration @@ -84,83 +76,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 ); - typedef struct { int numfilenames; @@ -222,14 +137,6 @@ typedef enum #define CIN_MAIN 0 #define CIN_LOGO 1 -// config strings are a general means of communication from -// the server to all connected clients. -// each config string can be at most CS_SIZE characters. -#define MAX_QPATH 64 // max length of a game pathname -#define MAX_OSPATH 260 // max length of a filesystem pathname -#define CS_SIZE 64 // size of one config string -#define CS_TIME 16 // size of time string - #define MAX_DECALS 512 // touching TE_DECAL messages, etc #define MAX_STATIC_ENTITIES 3096 // static entities that moved on the client when level is spawn @@ -555,6 +462,71 @@ typedef struct host_parm_s extern host_parm_t host; extern sysinfo_t SI; +#define CMD_SERVERDLL BIT( 0 ) // added by server.dll +#define CMD_CLIENTDLL BIT( 1 ) // added by client.dll +#define CMD_GAMEUIDLL BIT( 2 ) // added by GameUI.dll +#define CMD_LOCALONLY BIT( 3 ) // restricted from server commands +#define CMD_REFDLL BIT( 4 ) // added by ref.dll + +typedef void (*xcommand_t)( void ); + +// +// cmd.c +// +void Cbuf_Init( void ); +void Cbuf_Clear( void ); +void Cbuf_AddText( const char *text ); +void Cbuf_InsertText( const char *text ); +void Cbuf_ExecStuffCmds( void ); +void Cbuf_Execute (void); +int Cmd_Argc( void ); +const char *Cmd_Args( void ); +const char *Cmd_Argv( int arg ); +void Cmd_Init( void ); +void Cmd_Unlink( int group ); +void Cmd_AddCommand( const char *cmd_name, xcommand_t function, const char *cmd_desc ); +void Cmd_AddRestrictedCommand( const char *cmd_name, xcommand_t function, const char *cmd_desc ); +void Cmd_AddServerCommand( const char *cmd_name, xcommand_t function ); +int Cmd_AddClientCommand( const char *cmd_name, xcommand_t function ); +int Cmd_AddGameUICommand( const char *cmd_name, xcommand_t function ); +int Cmd_AddRefCommand( const char *cmd_name, xcommand_t function, const char *description ); +void Cmd_RemoveCommand( const char *cmd_name ); +qboolean Cmd_Exists( const char *cmd_name ); +void Cmd_LookupCmds( char *buffer, void *ptr, setpair_t callback ); +qboolean Cmd_GetMapList( const char *s, char *completedname, int length ); +qboolean Cmd_GetDemoList( const char *s, char *completedname, int length ); +qboolean Cmd_GetMovieList( const char *s, char *completedname, int length ); +void Cmd_TokenizeString( char *text ); +void Cmd_ExecuteString( char *text ); +void Cmd_ForwardToServer( void ); + +// +// zone.c +// +void Memory_Init( void ); +void *_Mem_Realloc( byte *poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline ); +void *_Mem_Alloc( byte *poolptr, size_t size, qboolean clear, const char *filename, int fileline ); +byte *_Mem_AllocPool( const char *name, const char *filename, int fileline ); +void _Mem_FreePool( byte **poolptr, const char *filename, int fileline ); +void _Mem_EmptyPool( byte *poolptr, const char *filename, int fileline ); +void _Mem_Free( void *data, const char *filename, int fileline ); +void _Mem_Check( const char *filename, int fileline ); +qboolean Mem_IsAllocatedExt( byte *poolptr, void *data ); +void Mem_PrintList( size_t minallocationsize ); +void Mem_PrintStats( void ); + +#ifndef REF_DLL +#define Mem_Malloc( pool, size ) _Mem_Alloc( pool, size, false, __FILE__, __LINE__ ) +#define Mem_Calloc( pool, size ) _Mem_Alloc( pool, size, true, __FILE__, __LINE__ ) +#define Mem_Realloc( pool, ptr, size ) _Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ ) +#define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ ) +#define Mem_AllocPool( name ) _Mem_AllocPool( name, __FILE__, __LINE__ ) +#define Mem_FreePool( pool ) _Mem_FreePool( pool, __FILE__, __LINE__ ) +#define Mem_EmptyPool( pool ) _Mem_EmptyPool( pool, __FILE__, __LINE__ ) +#define Mem_IsAllocated( mem ) Mem_IsAllocatedExt( NULL, mem ) +#define Mem_Check() _Mem_Check( __FILE__, __LINE__ ) +#endif + // // filesystem.c // @@ -567,13 +539,7 @@ void FS_AllowDirectPaths( qboolean enable ); void FS_AddGameDirectory( const char *dir, uint flags ); void FS_AddGameHierarchy( const char *dir, uint flags ); void FS_LoadGameInfo( const char *rootfolder ); -void COM_FileBase( const char *in, char *out ); -const char *COM_FileExtension( const char *in ); -void COM_DefaultExtension( char *path, const char *extension ); -void COM_ReplaceExtension( char *path, const char *extension ); -void COM_ExtractFilePath( const char *path, char *dest ); const char *FS_GetDiskPath( const char *name, qboolean gamedironly ); -const char *COM_FileWithoutPath( const char *in ); byte *W_LoadLump( wfile_t *wad, const char *lumpname, size_t *lumpsizeptr, const char type ); void W_Close( wfile_t *wad ); byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly ); @@ -584,7 +550,6 @@ void COM_NormalizeAngles( vec3_t angles ); int COM_FileSize( const char *filename ); void COM_FixSlashes( char *pname ); void COM_FreeFile( void *buffer ); -int COM_CheckString( const char *string ); int COM_CompareFileTime( const char *filename1, const char *filename2, int *iCompare ); search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly ); file_t *FS_Open( const char *filepath, const char *mode, qboolean gamedironly ); @@ -603,124 +568,17 @@ qboolean FS_SysFileExists( const char *path, qboolean casesensitive ); qboolean FS_FileCopy( file_t *pOutput, file_t *pInput, int fileSize ); qboolean FS_Delete( const char *path ); int FS_UnGetc( file_t *file, byte c ); -void COM_StripExtension( char *path ); fs_offset_t FS_Tell( file_t *file ); qboolean FS_Eof( file_t *file ); 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 +596,6 @@ qboolean Image_CustomPalette( void ); void Image_ClearForceFlags( void ); void Image_SetMDLPointer( byte *p ); void Image_CheckPaletteQ1( void ); - /* ======================================================================== @@ -899,6 +756,10 @@ void Con_Printf( const char *szFmt, ... ) _format( 1 ); int pfnNumberOfEntities( void ); int pfnIsInGame( void ); float pfnTime( void ); +#define copystring( s ) _copystring( host.mempool, s, __FILE__, __LINE__ ) +#define SV_CopyString( s ) _copystring( svgame.stringspool, s, __FILE__, __LINE__ ) +#define freestring( s ) if( s != NULL ) { Mem_Free( s ); s = NULL; } +char *_copystring( byte *mempool, const char *s, const char *filename, int fileline ); // CS:CS engfuncs (stubs) void *pfnSequenceGet( const char *fileName, const char *entryName ); @@ -1029,9 +890,8 @@ void SV_BroadcastCommand( const char *fmt, ... ) _format( 1 ); qboolean SV_RestoreCustomDecal( struct decallist_s *entry, edict_t *pEdict, qboolean adjacent ); void SV_BroadcastPrintf( sv_client_t *ignore, char *fmt, ... ) _format( 2 ); int R_CreateDecalList( struct decallist_s *pList ); -void R_DecalRemoveAll( int texture ); void R_ClearAllDecals( void ); -void R_ClearStaticEntities( void ); +void CL_ClearStaticEntities( void ); qboolean S_StreamGetCurrentState( char *currentTrack, char *loopTrack, int *position ); struct cl_entity_s *CL_GetEntityByIndex( int index ); struct player_info_s *CL_GetPlayerInfo( int playerIndex ); @@ -1058,7 +918,6 @@ int SV_GetSaveComment( const char *savename, char *comment ); qboolean SV_NewGame( const char *mapName, qboolean loadGame ); void SV_ClipPMoveToEntity( struct physent_s *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, struct pmtrace_s *tr ); void CL_ClipPMoveToEntity( struct physent_s *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, struct pmtrace_s *tr ); -void CL_Particle( const vec3_t origin, int color, float life, int zpos, int zvel ); // debug thing void SV_SysError( const char *error_string ); void SV_ShutdownGame( void ); void SV_ExecLoadLevel( void ); @@ -1104,9 +963,9 @@ qboolean LZSS_IsCompressed( const byte *source ); uint LZSS_GetActualSize( const byte *source ); byte *LZSS_Compress( byte *pInput, int inputLength, uint *pOutputSize ); uint LZSS_Decompress( const byte *pInput, byte *pOutput ); -const byte *GL_TextureData( unsigned int texnum ); void GL_FreeImage( const char *name ); void VID_InitDefaultResolution( void ); +void VID_Init( void ); void UI_SetActiveMenu( qboolean fActive ); void Cmd_Null_f( void ); @@ -1145,6 +1004,10 @@ void NET_InitMasters( void ); void NET_SaveMasters( void ); qboolean NET_SendToMasters( netsrc_t sock, size_t len, const void *data ); +#ifdef REF_DLL +#error "common.h in ref_dll" +#endif + #ifdef __cplusplus } #endif diff --git a/engine/common/crtlib.h b/engine/common/crtlib.h deleted file mode 100644 index c9ee170c..00000000 --- a/engine/common/crtlib.h +++ /dev/null @@ -1,139 +0,0 @@ -/* -crtlib.h - internal stdlib -Copyright (C) 2011 Uncle Mike - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -*/ - -#ifndef STDLIB_H -#define STDLIB_H - -#ifdef __GNUC__ -#define _format(x) __attribute__((format(printf, x, x+1))) -#else -#define _format(x) -#endif - -// timestamp modes -enum -{ - TIME_FULL = 0, - TIME_DATE_ONLY, - TIME_TIME_ONLY, - TIME_NO_SECONDS, - TIME_YEAR_ONLY, - TIME_FILENAME, -}; - -#define CMD_SERVERDLL BIT( 0 ) // added by server.dll -#define CMD_CLIENTDLL BIT( 1 ) // added by client.dll -#define CMD_GAMEUIDLL BIT( 2 ) // added by GameUI.dll -#define CMD_LOCALONLY BIT( 3 ) // restricted from server commands - -typedef void (*xcommand_t)( void ); - -// -// cmd.c -// -void Cbuf_Init( void ); -void Cbuf_Clear( void ); -void Cbuf_AddText( const char *text ); -void Cbuf_InsertText( const char *text ); -void Cbuf_ExecStuffCmds( void ); -void Cbuf_Execute (void); -int Cmd_Argc( void ); -const char *Cmd_Args( void ); -const char *Cmd_Argv( int arg ); -void Cmd_Init( void ); -void Cmd_Unlink( int group ); -void Cmd_AddCommand( const char *cmd_name, xcommand_t function, const char *cmd_desc ); -void Cmd_AddRestrictedCommand( const char *cmd_name, xcommand_t function, const char *cmd_desc ); -void Cmd_AddServerCommand( const char *cmd_name, xcommand_t function ); -int Cmd_AddClientCommand( const char *cmd_name, xcommand_t function ); -int Cmd_AddGameUICommand( const char *cmd_name, xcommand_t function ); -void Cmd_RemoveCommand( const char *cmd_name ); -qboolean Cmd_Exists( const char *cmd_name ); -void Cmd_LookupCmds( char *buffer, void *ptr, setpair_t callback ); -qboolean Cmd_GetMapList( const char *s, char *completedname, int length ); -qboolean Cmd_GetDemoList( const char *s, char *completedname, int length ); -qboolean Cmd_GetMovieList( const char *s, char *completedname, int length ); -void Cmd_TokenizeString( char *text ); -void Cmd_ExecuteString( char *text ); -void Cmd_ForwardToServer( void ); - -// -// crtlib.c -// -#define Q_strupr( in, out ) Q_strnupr( in, out, 99999 ) -void Q_strnupr( const char *in, char *out, size_t size_out ); -#define Q_strlwr( in, out ) Q_strnlwr( in, out, 99999 ) -void Q_strnlwr( const char *in, char *out, size_t size_out ); -int Q_strlen( const char *string ); -int Q_colorstr( const char *string ); -char Q_toupper( const char in ); -char Q_tolower( const char in ); -#define Q_strcat( dst, src ) Q_strncat( dst, src, 99999 ) -size_t Q_strncat( char *dst, const char *src, size_t siz ); -#define Q_strcpy( dst, src ) Q_strncpy( dst, src, 99999 ) -size_t Q_strncpy( char *dst, const char *src, size_t siz ); -#define copystring( s ) _copystring( host.mempool, s, __FILE__, __LINE__ ) -#define SV_CopyString( s ) _copystring( svgame.stringspool, s, __FILE__, __LINE__ ) -#define freestring( s ) if( s != NULL ) { Mem_Free( s ); s = NULL; } -char *_copystring( byte *mempool, const char *s, const char *filename, int fileline ); -uint Q_hashkey( const char *string, uint hashSize, qboolean caseinsensitive ); -qboolean Q_isdigit( const char *str ); -int Q_atoi( const char *str ); -float Q_atof( const char *str ); -void Q_atov( float *vec, const char *str, size_t siz ); -char *Q_strchr( const char *s, char c ); -char *Q_strrchr( const char *s, char c ); -#define Q_stricmp( s1, s2 ) Q_strnicmp( s1, s2, 99999 ) -int Q_strnicmp( const char *s1, const char *s2, int n ); -#define Q_strcmp( s1, s2 ) Q_strncmp( s1, s2, 99999 ) -int Q_strncmp( const char *s1, const char *s2, int n ); -qboolean Q_stricmpext( const char *s1, const char *s2 ); -const char *Q_timestamp( int format ); -char *Q_stristr( const char *string, const char *string2 ); -char *Q_strstr( const char *string, const char *string2 ); -#define Q_vsprintf( buffer, format, args ) Q_vsnprintf( buffer, 99999, format, args ) -int Q_vsnprintf( char *buffer, size_t buffersize, const char *format, va_list args ); -int Q_snprintf( char *buffer, size_t buffersize, const char *format, ... ) _format( 3 ); -int Q_sprintf( char *buffer, const char *format, ... ) _format( 2 ); -#define Q_memprint( val ) Q_pretifymem( val, 2 ) -char *Q_pretifymem( float value, int digitsafterdecimal ); -char *va( const char *format, ... ) _format( 1 ); - -// -// zone.c -// -void Memory_Init( void ); -void *_Mem_Realloc( byte *poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline ); -void *_Mem_Alloc( byte *poolptr, size_t size, qboolean clear, const char *filename, int fileline ); -byte *_Mem_AllocPool( const char *name, const char *filename, int fileline ); -void _Mem_FreePool( byte **poolptr, const char *filename, int fileline ); -void _Mem_EmptyPool( byte *poolptr, const char *filename, int fileline ); -void _Mem_Free( void *data, const char *filename, int fileline ); -void _Mem_Check( const char *filename, int fileline ); -qboolean Mem_IsAllocatedExt( byte *poolptr, void *data ); -void Mem_PrintList( size_t minallocationsize ); -void Mem_PrintStats( void ); - -#define Mem_Malloc( pool, size ) _Mem_Alloc( pool, size, false, __FILE__, __LINE__ ) -#define Mem_Calloc( pool, size ) _Mem_Alloc( pool, size, true, __FILE__, __LINE__ ) -#define Mem_Realloc( pool, ptr, size ) _Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ ) -#define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ ) -#define Mem_AllocPool( name ) _Mem_AllocPool( name, __FILE__, __LINE__ ) -#define Mem_FreePool( pool ) _Mem_FreePool( pool, __FILE__, __LINE__ ) -#define Mem_EmptyPool( pool ) _Mem_EmptyPool( pool, __FILE__, __LINE__ ) -#define Mem_IsAllocated( mem ) Mem_IsAllocatedExt( NULL, mem ) -#define Mem_Check() _Mem_Check( __FILE__, __LINE__ ) - -#endif//STDLIB_H diff --git a/engine/common/custom.c b/engine/common/custom.c index a379b38b..7b8c2736 100644 --- a/engine/common/custom.c +++ b/engine/common/custom.c @@ -15,6 +15,7 @@ GNU General Public License for more details. #include "common.h" #include "custom.h" +#include "ref_common.h" qboolean CustomDecal_Validate( void *raw, int nFileSize ) { @@ -48,7 +49,7 @@ void COM_ClearCustomizationList( customization_t *pHead, qboolean bCleanDecals ) if( pCurrent->resource.type == t_decal ) { if( bCleanDecals && CL_Active( )) - R_DecalRemoveAll( pCurrent->nUserData1 ); + ref.dllFuncs.R_DecalRemoveAll( pCurrent->nUserData1 ); } #endif diff --git a/engine/common/dedicated.c b/engine/common/dedicated.c index db647c76..d1c9773b 100644 --- a/engine/common/dedicated.c +++ b/engine/common/dedicated.c @@ -15,6 +15,9 @@ GNU General Public License for more details. #ifdef XASH_DEDICATED #include "common.h" #include "mathlib.h" +#include "ref_api.h" + +ref_globals_t refState; const char *svc_strings[256] = { @@ -319,189 +322,9 @@ void CL_StopPlayback( void ) } -#include "sprite.h" - -/* -==================== -Mod_LoadSpriteModel - -load sprite model -==================== -*/ -void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags ) +void CL_ClearStaticEntities( void ) { - dsprite_q1_t *pinq1; - dsprite_hl_t *pinhl; - dsprite_t *pin; - short *numi = NULL; - dframetype_t *pframetype; - msprite_t *psprite; - int i, size; - if( loaded ) *loaded = false; - pin = (dsprite_t *)buffer; - mod->type = mod_sprite; - i = pin->version; - - if( pin->ident != IDSPRITEHEADER ) - { - Con_Reportf( S_ERROR "%s has wrong id (%x should be %x)\n", mod->name, pin->ident, IDSPRITEHEADER ); - return; - } - - if( i != SPRITE_VERSION_Q1 && i != SPRITE_VERSION_HL && i != SPRITE_VERSION_32 ) - { - Con_Reportf( S_ERROR "%s has wrong version number (%i should be %i or %i)\n", mod->name, i, SPRITE_VERSION_Q1, SPRITE_VERSION_HL ); - return; - } - - mod->mempool = Mem_AllocPool( va( "^2%s^7", mod->name )); - - if( i == SPRITE_VERSION_Q1 || i == SPRITE_VERSION_32 ) - { - pinq1 = (dsprite_q1_t *)buffer; - size = sizeof( msprite_t ) + ( pinq1->numframes - 1 ) * sizeof( psprite->frames ); - psprite = Mem_Calloc( mod->mempool, size ); - mod->cache.data = psprite; // make link to extradata - - psprite->type = pinq1->type; - psprite->texFormat = SPR_ADDITIVE; //SPR_ALPHTEST; - psprite->numframes = mod->numframes = pinq1->numframes; - psprite->facecull = SPR_CULL_FRONT; - psprite->radius = pinq1->boundingradius; - psprite->synctype = pinq1->synctype; - - mod->mins[0] = mod->mins[1] = -pinq1->bounds[0] * 0.5f; - mod->maxs[0] = mod->maxs[1] = pinq1->bounds[0] * 0.5f; - mod->mins[2] = -pinq1->bounds[1] * 0.5f; - mod->maxs[2] = pinq1->bounds[1] * 0.5f; - numi = NULL; - } - else if( i == SPRITE_VERSION_HL ) - { - pinhl = (dsprite_hl_t *)buffer; - size = sizeof( msprite_t ) + ( pinhl->numframes - 1 ) * sizeof( psprite->frames ); - psprite = Mem_Calloc( mod->mempool, size ); - mod->cache.data = psprite; // make link to extradata - - psprite->type = pinhl->type; - psprite->texFormat = pinhl->texFormat; - psprite->numframes = mod->numframes = pinhl->numframes; - psprite->facecull = pinhl->facetype; - psprite->radius = pinhl->boundingradius; - psprite->synctype = pinhl->synctype; - - mod->mins[0] = mod->mins[1] = -pinhl->bounds[0] * 0.5f; - mod->maxs[0] = mod->maxs[1] = pinhl->bounds[0] * 0.5f; - mod->mins[2] = -pinhl->bounds[1] * 0.5f; - mod->maxs[2] = pinhl->bounds[1] * 0.5f; - numi = (short *)(pinhl + 1); - } - - if( Host_IsDedicated() ) - { - // skip frames loading - if( loaded ) *loaded = true; // done - psprite->numframes = 0; - return; - } - - if( numi == NULL ) - { - rgbdata_t *pal; - - pal = FS_LoadImage( "#id.pal", (byte *)&i, 768 ); - pframetype = (dframetype_t *)(pinq1 + 1); - FS_FreeImage( pal ); // palette installed, no reason to keep this data - } - else if( *numi == 256 ) - { - byte *src = (byte *)(numi+1); - rgbdata_t *pal; - - // install palette - switch( psprite->texFormat ) - { - case SPR_INDEXALPHA: - pal = FS_LoadImage( "#gradient.pal", src, 768 ); - break; - case SPR_ALPHTEST: - pal = FS_LoadImage( "#masked.pal", src, 768 ); - break; - default: - pal = FS_LoadImage( "#normal.pal", src, 768 ); - break; - } - - pframetype = (dframetype_t *)(src + 768); - FS_FreeImage( pal ); // palette installed, no reason to keep this data - } - else - { - Con_Reportf( S_ERROR "%s has wrong number of palette colors %i (should be 256)\n", mod->name, *numi ); - return; - } - - if( mod->numframes < 1 ) - { - Con_Reportf( S_ERROR "%s has invalid # of frames: %d\n", mod->name, mod->numframes ); - return; - } - - if( loaded ) *loaded = true; // done -} - -/* -==================== -Mod_UnloadSpriteModel - -release sprite model and frames -==================== -*/ -void Mod_UnloadSpriteModel( model_t *mod ) -{ - msprite_t *psprite; - mspritegroup_t *pspritegroup; - mspriteframe_t *pspriteframe; - int i, j; - - Assert( mod != NULL ); - -#ifndef XASH_DEDICATED - if( mod->type == mod_sprite ) - { - if( host.type != HOST_DEDICATED ) - { - psprite = mod->cache.data; - - if( psprite ) - { - // release all textures - for( i = 0; i < psprite->numframes; i++ ) - { - if( psprite->frames[i].type == SPR_SINGLE ) - { - pspriteframe = psprite->frames[i].frameptr; - GL_FreeTexture( pspriteframe->gl_texturenum ); - } - else - { - pspritegroup = (mspritegroup_t *)psprite->frames[i].frameptr; - - for( j = 0; j < pspritegroup->numframes; j++ ) - { - pspriteframe = pspritegroup->frames[i]; - GL_FreeTexture( pspriteframe->gl_texturenum ); - } - } - } - } - } - } -#endif - - Mem_FreePool( &mod->mempool ); - memset( mod, 0, sizeof( *mod )); } #endif // XASH_DEDICATED diff --git a/engine/common/gamma.c b/engine/common/gamma.c index e4ccabaa..a7b7d010 100644 --- a/engine/common/gamma.c +++ b/engine/common/gamma.c @@ -15,7 +15,6 @@ GNU General Public License for more details. #include "common.h" #include -#include "gl_local.h" //----------------------------------------------------------------------------- // Gamma conversion support @@ -85,4 +84,4 @@ byte LightToTexGamma( byte b ) byte TextureToGamma( byte b ) { return texgammatable[b]; -} \ No newline at end of file +} diff --git a/engine/common/imagelib/img_utils.c b/engine/common/imagelib/img_utils.c index 934dfb54..13e6bb7e 100644 --- a/engine/common/imagelib/img_utils.c +++ b/engine/common/imagelib/img_utils.c @@ -16,7 +16,6 @@ GNU General Public License for more details. #include "imagelib.h" #include "mathlib.h" #include "mod_local.h" -#include "gl_export.h" #define LERPBYTE( i ) r = resamplerow1[i]; out[i] = (byte)(((( resamplerow2[i] - r ) * lerp)>>16 ) + r ) #define FILTER_SIZE 5 @@ -1534,4 +1533,4 @@ qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, floa image.force_flags = 0; return result; -} \ No newline at end of file +} diff --git a/engine/common/imagelib/img_wad.c b/engine/common/imagelib/img_wad.c index c47b42f5..147d69cb 100644 --- a/engine/common/imagelib/img_wad.c +++ b/engine/common/imagelib/img_wad.c @@ -137,7 +137,7 @@ Transfer buffer pointer before Image_LoadMDL ====================== */ static void *g_mdltexdata; -void Image_SetMDLPointer(byte *p) +void Image_SetMDLPointer( byte *p ) { g_mdltexdata = p; } diff --git a/engine/common/mod_bmodel.c b/engine/common/mod_bmodel.c index dad9490c..7a203700 100644 --- a/engine/common/mod_bmodel.c +++ b/engine/common/mod_bmodel.c @@ -12,7 +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 "mod_local.h" #include "sprite.h" #include "mathlib.h" @@ -20,11 +20,10 @@ GNU General Public License for more details. #include "studio.h" #include "wadfile.h" #include "world.h" -#include "gl_local.h" #include "enginefeatures.h" #include "client.h" #include "server.h" // LUMP_ error codes - +#include "ref_common.h" typedef struct wadlist_s { char wadnames[MAX_MAP_WADS][32]; @@ -1033,7 +1032,7 @@ static void Mod_CalcSurfaceExtents( msurface_t *surf ) info->lightextents[i] = surf->extents[i]; } -#ifndef XASH_DEDICATED +#if !defined XASH_DEDICATED && 0 // REFTODO: if( !FBitSet( tex->flags, TEX_SPECIAL ) && ( surf->extents[i] > 16384 ) && ( tr.block_size == BLOCK_SIZE_DEFAULT )) Con_Reportf( S_ERROR "Bad surface extents %i\n", surf->extents[i] ); #endif // XASH_DEDICATED @@ -1473,8 +1472,8 @@ static void Mod_LoadSubmodels( dbspmodel_t *bmod ) in = bmod->submodels; if( bmod->isworld ) - world.max_surfaces = 0; - oldmaxfaces = world.max_surfaces; + refState.max_surfaces = 0; + oldmaxfaces = refState.max_surfaces; for( i = 0; i < bmod->numsubmodels; i++, in++, out++ ) { @@ -1505,10 +1504,10 @@ static void Mod_LoadSubmodels( dbspmodel_t *bmod ) } // these array used to sort translucent faces in bmodels - if( oldmaxfaces > world.max_surfaces ) + if( oldmaxfaces > refState.max_surfaces ) { - world.draw_surfaces = (sortedface_t *)Z_Realloc( world.draw_surfaces, oldmaxfaces * sizeof( sortedface_t )); - world.max_surfaces = oldmaxfaces; + refState.draw_surfaces = (sortedface_t *)Z_Realloc( refState.draw_surfaces, oldmaxfaces * sizeof( sortedface_t )); + refState.max_surfaces = oldmaxfaces; } } @@ -1802,10 +1801,8 @@ static void Mod_LoadTextures( dbspmodel_t *bmod ) { #ifndef XASH_DEDICATED // release old sky layers first - GL_FreeTexture( tr.solidskyTexture ); - GL_FreeTexture( tr.alphaskyTexture ); - tr.solidskyTexture = 0; - tr.alphaskyTexture = 0; + ref.dllFuncs.R_FreeSharedTexture( REF_ALPHASKY_TEXTURE ); + ref.dllFuncs.R_FreeSharedTexture( REF_SOLIDSKY_TEXTURE ); #endif } @@ -1830,7 +1827,7 @@ static void Mod_LoadTextures( dbspmodel_t *bmod ) Q_strncpy( tx->name, "*default", sizeof( tx->name )); #ifndef XASH_DEDICATED - tx->gl_texturenum = tr.defaultTexture; + tx->gl_texturenum = ref.dllFuncs.R_GetBuiltinTexture( REF_DEFAULT_TEXTURE ); tx->width = tx->height = 16; #endif continue; // missed @@ -1850,7 +1847,6 @@ static void Mod_LoadTextures( dbspmodel_t *bmod ) tx->width = mt->width; tx->height = mt->height; - if( mt->offsets[0] > 0 ) { int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6); @@ -1876,9 +1872,10 @@ static void Mod_LoadTextures( dbspmodel_t *bmod ) // check for multi-layered sky texture (quake1 specific) if( bmod->isworld && !Q_strncmp( mt->name, "sky", 3 ) && (( mt->width / mt->height ) == 2 )) { - R_InitSkyClouds( mt, tx, custom_palette ); // load quake sky + ref.dllFuncs.R_InitSkyClouds( mt, tx, custom_palette ); // load quake sky - if( tr.solidskyTexture && tr.alphaskyTexture ) + if( ref.dllFuncs.R_GetBuiltinTexture( REF_SOLIDSKY_TEXTURE ) && + ref.dllFuncs.R_GetBuiltinTexture( REF_ALPHASKY_TEXTURE ) ) SetBits( world.flags, FWORLD_SKYSPHERE ); continue; } @@ -1899,7 +1896,7 @@ static void Mod_LoadTextures( dbspmodel_t *bmod ) if( FS_FileExists( texpath, false )) { - tx->gl_texturenum = GL_LoadTexture( texpath, NULL, 0, TF_ALLOW_EMBOSS ); + tx->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texpath, NULL, 0, TF_ALLOW_EMBOSS ); bmod->wadlist.wadusage[j]++; // this wad are really used break; } @@ -1915,7 +1912,7 @@ static void Mod_LoadTextures( dbspmodel_t *bmod ) if( custom_palette ) size += sizeof( short ) + 768; Q_snprintf( texname, sizeof( texname ), "#%s:%s.mip", loadstat.name, mt->name ); - tx->gl_texturenum = GL_LoadTexture( texname, (byte *)mt, size, TF_ALLOW_EMBOSS ); + tx->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texname, (byte *)mt, size, TF_ALLOW_EMBOSS ); } // if texture is completely missed @@ -1923,11 +1920,11 @@ static void Mod_LoadTextures( dbspmodel_t *bmod ) { if( host.type != HOST_DEDICATED ) Con_DPrintf( S_ERROR "unable to find %s.mip\n", mt->name ); - tx->gl_texturenum = tr.defaultTexture; + tx->gl_texturenum = ref.dllFuncs.R_GetBuiltinTexture( REF_DEFAULT_TEXTURE ); } // check for luma texture - if( FBitSet( R_GetTexture( tx->gl_texturenum )->flags, TF_HAS_LUMA )) + if( FBitSet( REF_GET_PARM( PARM_TEX_FLAGS, tx->gl_texturenum ), TF_HAS_LUMA )) { Q_snprintf( texname, sizeof( texname ), "#%s:%s_luma.mip", loadstat.name, mt->name ); @@ -1938,7 +1935,7 @@ static void Mod_LoadTextures( dbspmodel_t *bmod ) int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6); if( custom_palette ) size += sizeof( short ) + 768; - tx->fb_texturenum = GL_LoadTexture( texname, (byte *)mt, size, TF_MAKELUMA ); + tx->fb_texturenum = ref.dllFuncs.GL_LoadTexture( texname, (byte *)mt, size, TF_MAKELUMA ); } else { @@ -1963,7 +1960,7 @@ static void Mod_LoadTextures( dbspmodel_t *bmod ) } // okay, loading it from wad or hi-res version - tx->fb_texturenum = GL_LoadTexture( texname, src, srcSize, TF_MAKELUMA ); + tx->fb_texturenum = ref.dllFuncs.GL_LoadTexture( texname, src, srcSize, TF_MAKELUMA ); if( src ) Mem_Free( src ); } } @@ -2246,7 +2243,7 @@ static void Mod_LoadSurfaces( dbspmodel_t *bmod ) #ifndef XASH_DEDICATED // TODO: Do we need subdivide on server? if( FBitSet( out->flags, SURF_DRAWTURB )) - GL_SubdivideSurface( out ); // cut up polygon for warps + ref.dllFuncs.GL_SubdivideSurface( out ); // cut up polygon for warps #endif } @@ -2355,6 +2352,7 @@ static void Mod_LoadLeafs( dbspmodel_t *bmod ) visclusters = loadmodel->submodels[0].visleafs; world.visbytes = (visclusters + 7) >> 3; world.fatbytes = (visclusters + 31) >> 3; + refState.visbytes = world.visbytes; } for( i = 0; i < bmod->numleafs; i++, out++ ) @@ -2799,42 +2797,6 @@ void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *loaded ) if( loaded ) *loaded = true; // all done } -/* -================= -Mod_UnloadBrushModel - -Release all uploaded textures -================= -*/ -void Mod_UnloadBrushModel( model_t *mod ) -{ - texture_t *tx; - int i; - - Assert( mod != NULL ); - - if( mod->type != mod_brush ) - return; // not a bmodel - - if( mod->name[0] != '*' ) - { -#ifndef XASH_DEDICATED - for( i = 0; i < mod->numtextures; i++ ) - { - tx = mod->textures[i]; - if( !tx || tx->gl_texturenum == tr.defaultTexture ) - continue; // free slot - - GL_FreeTexture( tx->gl_texturenum ); // main texture - GL_FreeTexture( tx->fb_texturenum ); // luma texture - } -#endif - Mem_FreePool( &mod->mempool ); - } - - memset( mod, 0, sizeof( *mod )); -} - /* ================== Mod_CheckLump diff --git a/engine/common/mod_local.h b/engine/common/mod_local.h index b83d9491..2ef00134 100644 --- a/engine/common/mod_local.h +++ b/engine/common/mod_local.h @@ -16,28 +16,10 @@ GNU General Public License for more details. #ifndef MOD_LOCAL_H #define MOD_LOCAL_H -#include "common.h" +//#include "common.h" #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 +#include "ref_api.h" #define LM_SAMPLE_SIZE 16 #define LM_SAMPLE_EXTRASIZE 8 @@ -54,22 +36,6 @@ GNU General Public License for more details. #define WORLD_INDEX (1) // world index is always 1 -// model flags (stored in model_t->flags) -#define MODEL_CONVEYOR BIT( 0 ) -#define MODEL_HAS_ORIGIN BIT( 1 ) -#define MODEL_LIQUID BIT( 2 ) // model has only point hull -#define MODEL_TRANSPARENT BIT( 3 ) // have transparent surfaces -#define MODEL_COLORED_LIGHTING BIT( 4 ) // lightmaps stored as RGB - -#define MODEL_WORLD BIT( 29 ) // it's a worldmodel -#define MODEL_CLIENT BIT( 30 ) // client sprite - -// goes into world.flags -#define FWORLD_SKYSPHERE BIT( 0 ) -#define FWORLD_CUSTOM_SKYBOX BIT( 1 ) -#define FWORLD_WATERALPHA BIT( 2 ) -#define FWORLD_HAS_DELUXEMAP BIT( 3 ) - typedef struct consistency_s { const char *filename; @@ -116,13 +82,8 @@ typedef struct uint num_polys; } hull_model_t; -typedef struct -{ - msurface_t *surf; - int cull; -} sortedface_t; -typedef struct +typedef struct world_static_s { qboolean loading; // true if worldmodel is loading int flags; // misc flags @@ -132,10 +93,6 @@ typedef struct char compiler[256]; // map compiler char generator[256]; // map editor - // translucent sorted array - sortedface_t *draw_surfaces; // used for sorting translucent surfaces - int max_surfaces; // max surfaces per submodel (for all models) - hull_model_t *hull_models; int num_hull_models; @@ -149,6 +106,7 @@ typedef struct vec3_t size; } world_static_t; +#ifndef REF_DLL extern world_static_t world; extern byte *com_studiocache; extern model_t *loadmodel; @@ -160,6 +118,7 @@ extern convar_t *r_showhull; // model.c // void Mod_Init( void ); +void Mod_FreeModel( model_t *mod ); void Mod_FreeAll( void ); void Mod_Shutdown( void ); void Mod_ClearUserData( void ); @@ -209,6 +168,8 @@ typedef struct studiohdr_s studiohdr_t; typedef struct mstudioseqdesc_s mstudioseqdesc_t; typedef struct mstudiobone_s mstudiobone_t; typedef struct mstudioanim_s mstudioanim_t; +void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded ); +void Mod_UnloadStudioModel( model_t *mod ); void Mod_InitStudioAPI( void ); void Mod_InitStudioHull( void ); void Mod_ResetStudioAPI( void ); @@ -222,9 +183,13 @@ void R_StudioCalcBoneQuaternion( int frame, float s, mstudiobone_t *pbone, mstud void R_StudioCalcBonePosition( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, vec3_t adj, vec3_t pos ); void *R_StudioGetAnim( studiohdr_t *m_pStudioHeader, model_t *m_pSubModel, mstudioseqdesc_t *pseqdesc ); void Mod_StudioComputeBounds( void *buffer, vec3_t mins, vec3_t maxs, qboolean ignore_sequences ); -void Mod_StudioLoadTextures( model_t *mod, void *data ); -void Mod_StudioUnloadTextures( void *data ); int Mod_HitgroupForStudioHull( int index ); void Mod_ClearStudioCache( void ); +// +// mod_sprite.c +// +void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags ); +#endif + #endif//MOD_LOCAL_H diff --git a/engine/common/mod_sprite.c b/engine/common/mod_sprite.c new file mode 100644 index 00000000..952660eb --- /dev/null +++ b/engine/common/mod_sprite.c @@ -0,0 +1,111 @@ +/* +mod_sprite.c - sprite loading +Copyright (C) 2010 Uncle Mike +Copyright (C) 2019 a1batross + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + +#include "common.h" +#include "sprite.h" +#include "studio.h" +#ifndef XASH_DEDICATED +#include "ref_common.h" +#endif // XASH_DEDICATED + + +/* +==================== +Mod_LoadSpriteModel + +load sprite model +==================== +*/ +void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags ) +{ + dsprite_q1_t *pinq1; + dsprite_hl_t *pinhl; + dsprite_t *pin; + msprite_t *psprite; + int i, size; + + if( loaded ) *loaded = false; + pin = (dsprite_t *)buffer; + mod->type = mod_sprite; + i = pin->version; + + if( pin->ident != IDSPRITEHEADER ) + { + Con_DPrintf( S_ERROR "%s has wrong id (%x should be %x)\n", mod->name, pin->ident, IDSPRITEHEADER ); + return; + } + + if( i != SPRITE_VERSION_Q1 && i != SPRITE_VERSION_HL && i != SPRITE_VERSION_32 ) + { + Con_DPrintf( S_ERROR "%s has wrong version number (%i should be %i or %i)\n", mod->name, i, SPRITE_VERSION_Q1, SPRITE_VERSION_HL ); + return; + } + + mod->mempool = Mem_AllocPool( va( "^2%s^7", mod->name )); + + if( i == SPRITE_VERSION_Q1 || i == SPRITE_VERSION_32 ) + { + pinq1 = (dsprite_q1_t *)buffer; + size = sizeof( msprite_t ) + ( pinq1->numframes - 1 ) * sizeof( psprite->frames ); + psprite = Mem_Calloc( mod->mempool, size ); + mod->cache.data = psprite; // make link to extradata + + psprite->type = pinq1->type; + psprite->texFormat = SPR_ADDITIVE; //SPR_ALPHTEST; + psprite->numframes = mod->numframes = pinq1->numframes; + psprite->facecull = SPR_CULL_FRONT; + psprite->radius = pinq1->boundingradius; + psprite->synctype = pinq1->synctype; + + // LordHavoc: hack to allow sprites to be non-fullbright + for( i = 0; i < MAX_QPATH && mod->name[i]; i++ ) + if( mod->name[i] == '!' ) + psprite->texFormat = SPR_ALPHTEST; + + mod->mins[0] = mod->mins[1] = -pinq1->bounds[0] * 0.5f; + mod->maxs[0] = mod->maxs[1] = pinq1->bounds[0] * 0.5f; + mod->mins[2] = -pinq1->bounds[1] * 0.5f; + mod->maxs[2] = pinq1->bounds[1] * 0.5f; + } + else if( i == SPRITE_VERSION_HL ) + { + pinhl = (dsprite_hl_t *)buffer; + size = sizeof( msprite_t ) + ( pinhl->numframes - 1 ) * sizeof( psprite->frames ); + psprite = Mem_Calloc( mod->mempool, size ); + mod->cache.data = psprite; // make link to extradata + + psprite->type = pinhl->type; + psprite->texFormat = pinhl->texFormat; + psprite->numframes = mod->numframes = pinhl->numframes; + psprite->facecull = pinhl->facetype; + psprite->radius = pinhl->boundingradius; + psprite->synctype = pinhl->synctype; + + mod->mins[0] = mod->mins[1] = -pinhl->bounds[0] * 0.5f; + mod->maxs[0] = mod->maxs[1] = pinhl->bounds[0] * 0.5f; + mod->mins[2] = -pinhl->bounds[1] * 0.5f; + mod->maxs[2] = pinhl->bounds[1] * 0.5f; + } + if( loaded ) *loaded = true; // done + + if( Host_IsDedicated() ) + { + // skip frames loading + + psprite->numframes = 0; + return; + } +} diff --git a/engine/common/mod_studio.c b/engine/common/mod_studio.c index fc6d1da9..8f6fd9fd 100644 --- a/engine/common/mod_studio.c +++ b/engine/common/mod_studio.c @@ -18,6 +18,7 @@ GNU General Public License for more details. #include "studio.h" #include "r_studioint.h" #include "library.h" +#include "ref_common.h" typedef int (*STUDIOAPI)( int, sv_blending_interface_t**, server_studio_api_t*, float (*transform)[3][4], float (*bones)[MAXSTUDIOBONES][3][4] ); @@ -1047,65 +1048,68 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded ) phdr = R_StudioLoadHeader( mod, buffer ); if( !phdr ) return; // bad model -#ifndef XASH_DEDICATED - if( phdr->numtextures == 0 ) + if( !Host_IsDedicated() ) { - studiohdr_t *thdr; - byte *in, *out; - void *buffer2 = NULL; - size_t size1, size2; - - buffer2 = FS_LoadFile( Mod_StudioTexName( mod->name ), NULL, false ); - thdr = R_StudioLoadHeader( mod, buffer2 ); - - if( !thdr ) + if( phdr->numtextures == 0 ) { - Con_Printf( S_WARN "Mod_LoadStudioModel: %s missing textures file\n", mod->name ); - if( buffer2 ) Mem_Free( buffer2 ); + studiohdr_t *thdr; + byte *in, *out; + void *buffer2 = NULL; + size_t size1, size2; + + buffer2 = FS_LoadFile( Mod_StudioTexName( mod->name ), NULL, false ); + thdr = R_StudioLoadHeader( mod, buffer2 ); + + if( !thdr ) + { + Con_Printf( S_WARN "Mod_LoadStudioModel: %s missing textures file\n", mod->name ); + if( buffer2 ) Mem_Free( buffer2 ); + } + else + { + ref.dllFuncs.Mod_StudioLoadTextures( mod, thdr ); + + // give space for textures and skinrefs + size1 = thdr->numtextures * sizeof( mstudiotexture_t ); + size2 = thdr->numskinfamilies * thdr->numskinref * sizeof( short ); + mod->cache.data = Mem_Calloc( loadmodel->mempool, phdr->length + size1 + size2 ); + memcpy( loadmodel->cache.data, buffer, phdr->length ); // copy main mdl buffer + phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr + phdr->numskinfamilies = thdr->numskinfamilies; + phdr->numtextures = thdr->numtextures; + phdr->numskinref = thdr->numskinref; + phdr->textureindex = phdr->length; + phdr->skinindex = phdr->textureindex + size1; + + in = (byte *)thdr + thdr->textureindex; + out = (byte *)phdr + phdr->textureindex; + memcpy( out, in, size1 + size2 ); // copy textures + skinrefs + phdr->length += size1 + size2; + Mem_Free( buffer2 ); // release T.mdl + } } else { - Mod_StudioLoadTextures( mod, thdr ); - - // give space for textures and skinrefs - size1 = thdr->numtextures * sizeof( mstudiotexture_t ); - size2 = thdr->numskinfamilies * thdr->numskinref * sizeof( short ); - mod->cache.data = Mem_Calloc( loadmodel->mempool, phdr->length + size1 + size2 ); - memcpy( loadmodel->cache.data, buffer, phdr->length ); // copy main mdl buffer + // NOTE: don't modify source buffer because it's used for CRC computing + loadmodel->cache.data = Mem_Calloc( loadmodel->mempool, phdr->length ); + memcpy( loadmodel->cache.data, buffer, phdr->length ); phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr - phdr->numskinfamilies = thdr->numskinfamilies; - phdr->numtextures = thdr->numtextures; - phdr->numskinref = thdr->numskinref; - phdr->textureindex = phdr->length; - phdr->skinindex = phdr->textureindex + size1; + ref.dllFuncs.Mod_StudioLoadTextures( mod, phdr ); - in = (byte *)thdr + thdr->textureindex; - out = (byte *)phdr + phdr->textureindex; - memcpy( out, in, size1 + size2 ); // copy textures + skinrefs - phdr->length += size1 + size2; - Mem_Free( buffer2 ); // release T.mdl + // NOTE: we wan't keep raw textures in memory. just cutoff model pointer above texture base + loadmodel->cache.data = Mem_Realloc( loadmodel->mempool, loadmodel->cache.data, phdr->texturedataindex ); + phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr + phdr->length = phdr->texturedataindex; // update model size } } else { - // NOTE: don't modify source buffer because it's used for CRC computing + // just copy model into memory loadmodel->cache.data = Mem_Calloc( loadmodel->mempool, phdr->length ); memcpy( loadmodel->cache.data, buffer, phdr->length ); - phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr - Mod_StudioLoadTextures( mod, phdr ); - // NOTE: we wan't keep raw textures in memory. just cutoff model pointer above texture base - loadmodel->cache.data = Mem_Realloc( loadmodel->mempool, loadmodel->cache.data, phdr->texturedataindex ); - phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr - phdr->length = phdr->texturedataindex; // update model size + phdr = loadmodel->cache.data; } -#else - // just copy model into memory - loadmodel->cache.data = Mem_Calloc( loadmodel->mempool, phdr->length ); - memcpy( loadmodel->cache.data, buffer, phdr->length ); - - phdr = loadmodel->cache.data; -#endif // setup bounding box if( !VectorCompare( vec3_origin, phdr->bbmin )) @@ -1135,25 +1139,6 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded ) if( loaded ) *loaded = true; } -/* -================= -Mod_UnloadStudioModel -================= -*/ -void Mod_UnloadStudioModel( model_t *mod ) -{ - Assert( mod != NULL ); - - if( mod->type != mod_studio ) - return; // not a studio - -#ifndef XASH_DEDICATED - Mod_StudioUnloadTextures( mod->cache.data ); -#endif - Mem_FreePool( &mod->mempool ); - memset( mod, 0, sizeof( *mod )); -} - static sv_blending_interface_t gBlendAPI = { SV_BLENDING_INTERFACE_VERSION, diff --git a/engine/common/model.c b/engine/common/model.c index d80cb199..b87cd09c 100644 --- a/engine/common/model.c +++ b/engine/common/model.c @@ -12,7 +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 "mod_local.h" #include "sprite.h" #include "mathlib.h" @@ -20,7 +20,6 @@ GNU General Public License for more details. #include "studio.h" #include "wadfile.h" #include "world.h" -#include "gl_local.h" #include "enginefeatures.h" #include "client.h" #include "server.h" @@ -89,11 +88,7 @@ static void Mod_FreeUserData( model_t *mod ) #ifndef XASH_DEDICATED else { - if( clgame.drawFuncs.Mod_ProcessUserData != NULL ) - { - // let the client.dll free custom data - clgame.drawFuncs.Mod_ProcessUserData( mod, false, NULL ); - } + ref.dllFuncs.Mod_ProcessRenderData( mod, false, NULL ); } #endif } @@ -103,32 +98,16 @@ static void Mod_FreeUserData( model_t *mod ) Mod_FreeModel ================ */ -static void Mod_FreeModel( model_t *mod ) +void Mod_FreeModel( model_t *mod ) { // already freed? if( !mod || !mod->name[0] ) return; - if( mod->name[0] != '*' ) - Mod_FreeUserData( mod ); - - // select the properly unloader - switch( mod->type ) + if( mod->type != mod_brush || mod->name[0] != '*' ) { - case mod_sprite: - Mod_UnloadSpriteModel( mod ); - break; -#ifndef XASH_DEDICATED - case mod_alias: - Mod_UnloadAliasModel( mod ); - break; -#endif - case mod_studio: - Mod_UnloadStudioModel( mod ); - break; - case mod_brush: - Mod_UnloadBrushModel( mod ); - break; + Mod_FreeUserData( mod ); + Mem_FreePool( &mod->mempool ); } memset( mod, 0, sizeof( *mod )); @@ -308,16 +287,15 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash ) case IDSPRITEHEADER: Mod_LoadSpriteModel( mod, buf, &loaded, 0 ); break; - // TODO: Load alias models on dedicated too? -#ifndef XASH_DEDICATED case IDALIASHEADER: - Mod_LoadAliasModel( mod, buf, &loaded ); + // REFTODO: move server-related code here + loaded = true; break; -#endif case Q1BSP_VERSION: case HLBSP_VERSION: case QBSP2_VERSION: Mod_LoadBrushModel( mod, buf, &loaded ); + // ref.dllFuncs.Mod_LoadModel( mod_brush, mod, buf, &loaded, 0 ); break; default: Mem_Free( buf ); @@ -325,18 +303,7 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash ) else Con_Printf( S_ERROR "%s has unknown format\n", tempname ); return NULL; } - - if( !loaded ) - { - Mod_FreeModel( mod ); - Mem_Free( buf ); - - if( crash ) Host_Error( "Could not load model %s\n", tempname ); - else Con_Printf( S_ERROR "Could not load model %s\n", tempname ); - - return NULL; - } - else + if( loaded ) { if( world.loading ) SetBits( mod->flags, MODEL_WORLD ); // mark worldmodel @@ -352,15 +319,22 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash ) #ifndef XASH_DEDICATED else { - if( clgame.drawFuncs.Mod_ProcessUserData != NULL ) - { - // let the client.dll load custom data - clgame.drawFuncs.Mod_ProcessUserData( mod, true, buf ); - } + loaded = ref.dllFuncs.Mod_ProcessRenderData( mod, true, buf ); } #endif } + if( !loaded ) + { + Mod_FreeModel( mod ); + Mem_Free( buf ); + + if( crash ) Host_Error( "Could not load model %s\n", tempname ); + else Con_Printf( S_ERROR "Could not load model %s\n", tempname ); + + return NULL; + } + p = &mod_crcinfo[mod - mod_known]; mod->needload = NL_PRESENT; diff --git a/engine/common/net_ws.c b/engine/common/net_ws.c index 4a811398..ff4958fc 100644 --- a/engine/common/net_ws.c +++ b/engine/common/net_ws.c @@ -1891,7 +1891,7 @@ typedef struct httpserver_s { char host[256]; int port; - char path[PATH_MAX]; + char path[MAX_SYSPATH]; qboolean needfree; struct httpserver_s *next; @@ -1914,7 +1914,7 @@ typedef struct httpfile_s { struct httpfile_s *next; httpserver_t *server; - char path[PATH_MAX]; + char path[MAX_SYSPATH]; file_t *file; int socket; int size; @@ -2206,7 +2206,7 @@ void HTTP_Run( void ) if( curfile->state == HTTP_QUEUE ) { - char name[PATH_MAX]; + char name[MAX_SYSPATH]; if( iActiveCount > http_maxconnections->value ) continue; @@ -2219,7 +2219,7 @@ void HTTP_Run( void ) } Con_Reportf( "HTTP: Starting download %s from %s\n", curfile->path, curfile->server->host ); - Q_snprintf( name, PATH_MAX, "%s.incomplete", curfile->path ); + Q_snprintf( name, sizeof( name ), "%s.incomplete", curfile->path ); curfile->file = FS_Open( name, "wb", true ); @@ -2384,7 +2384,9 @@ void HTTP_Run( void ) } // update progress +#ifndef XASH_DEDICATED Cvar_SetValue( "scr_download", flProgress/iProgressCount * 100 ); +#endif // XASH_DEDICATED HTTP_AutoClean(); } diff --git a/engine/common/pm_debug.c b/engine/common/pm_debug.c index 22f52db6..6bebdf70 100644 --- a/engine/common/pm_debug.c +++ b/engine/common/pm_debug.c @@ -16,6 +16,9 @@ GNU General Public License for more details. #include "common.h" #include "mathlib.h" #include "pm_local.h" +#ifndef XASH_DEDICATED +#include "client.h" // CL_Particle +#endif // expand debugging BBOX particle hulls by this many units. #define BOX_GAP 0.0f @@ -89,4 +92,4 @@ void PM_DrawBBox( const vec3_t mins, const vec3_t maxs, const vec3_t origin, int PM_DrawRectangle( p[boxpnt[i][1]], p[boxpnt[i][0]], p[boxpnt[i][2]], p[boxpnt[i][3]], pcolor, life ); } #endif // XASH_DEDICATED -} \ No newline at end of file +} 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/common/world.c b/engine/common/world.c index 7ec87b45..70db5f13 100644 --- a/engine/common/world.c +++ b/engine/common/world.c @@ -192,64 +192,3 @@ int RankForContents( int contents ) default: return 13; // any user contents has more priority than default } } - -/* -================== -BoxOnPlaneSide - -Returns 1, 2, or 1 + 2 -================== -*/ -int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const mplane_t *p ) -{ - float dist1, dist2; - int sides = 0; - - // general case - switch( p->signbits ) - { - case 0: - dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; - dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; - break; - case 1: - dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; - dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; - break; - case 2: - dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; - dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; - break; - case 3: - dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; - dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; - break; - case 4: - dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; - dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; - break; - case 5: - dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; - dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; - break; - case 6: - dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; - dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; - break; - case 7: - dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; - dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; - break; - default: - // shut up compiler - dist1 = dist2 = 0; - break; - } - - if( dist1 >= p->dist ) - sides = 1; - if( dist2 < p->dist ) - sides |= 2; - - return sides; -} \ No newline at end of file diff --git a/engine/common/world.h b/engine/common/world.h index 781496d5..bfcdc8c4 100644 --- a/engine/common/world.h +++ b/engine/common/world.h @@ -46,26 +46,8 @@ void ClearLink( link_t *l ); void World_MoveBounds( const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, vec3_t boxmins, vec3_t boxmaxs ); void World_TransformAABB( matrix4x4 transform, const vec3_t mins, const vec3_t maxs, vec3_t outmins, vec3_t outmaxs ); trace_t World_CombineTraces( trace_t *cliptrace, trace_t *trace, edict_t *touch ); -int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const mplane_t *p ); int RankForContents( int contents ); -#define BOX_ON_PLANE_SIDE( emins, emaxs, p ) \ - ((( p )->type < 3 ) ? \ - ( \ - ((p)->dist <= (emins)[(p)->type]) ? \ - 1 \ - : \ - ( \ - ((p)->dist >= (emaxs)[(p)->type]) ? \ - 2 \ - : \ - 3 \ - ) \ - ) \ - : \ - BoxOnPlaneSide(( emins ), ( emaxs ), ( p ))) - - #define check_angles( x ) ( (int)x == 90 || (int)x == 180 || (int)x == 270 || (int)x == -90 || (int)x == -180 || (int)x == -270 ) /* diff --git a/engine/eiface.h b/engine/eiface.h index 39d9e946..ecc5d113 100644 --- a/engine/eiface.h +++ b/engine/eiface.h @@ -398,6 +398,7 @@ struct playermove_s; struct clientdata_s; struct usercmd_s; struct edict_s; +struct netadr_s; typedef struct { diff --git a/engine/platform/platform.h b/engine/platform/platform.h index 9506fbef..c8b147df 100644 --- a/engine/platform/platform.h +++ b/engine/platform/platform.h @@ -82,13 +82,16 @@ typedef enum typedef struct vidmode_s vidmode_t; // Window -qboolean R_Init_Video( void ); +qboolean R_Init_Video( const int type ); void R_Free_Video( void ); qboolean VID_SetMode( void ); rserr_t R_ChangeDisplaySettings( int width, int height, qboolean fullscreen ); int R_MaxVideoModes(); vidmode_t*R_GetVideoMode( int num ); void* GL_GetProcAddress( const char *name ); // RenderAPI requirement +void GL_UpdateSwapInterval( void ); +int GL_SetAttribute( int attr, int val ); +int GL_GetAttribute( int attr, int *val ); /* ============================================================================== diff --git a/engine/platform/sdl/events.c b/engine/platform/sdl/events.c index d7f1d70a..c4f07255 100644 --- a/engine/platform/sdl/events.c +++ b/engine/platform/sdl/events.c @@ -24,7 +24,6 @@ GNU General Public License for more details. #include "events.h" #include "sound.h" #include "vid_common.h" -#include "gl_local.h" static int wheelbutton; @@ -214,10 +213,10 @@ static void SDLash_EventFilter( SDL_Event *event ) #ifdef TOUCHEMU if( mdown ) IN_TouchEvent( event_motion, 0, - event->motion.x/(float)glState.width, - event->motion.y/(float)glState.height, - event->motion.xrel/(float)glState.width, - event->motion.yrel/(float)glState.height ); + event->motion.x/(float)refState.width, + event->motion.y/(float)refState.height, + event->motion.xrel/(float)refState.width, + event->motion.yrel/(float)refState.height ); SDL_ShowCursor( true ); #endif break; @@ -227,8 +226,8 @@ static void SDLash_EventFilter( SDL_Event *event ) #ifdef TOUCHEMU mdown = event->button.state != SDL_RELEASED; IN_TouchEvent( event_down, 0, - event->button.x/(float)glState.width, - event->button.y/(float)glState.height, 0, 0); + event->button.x/(float)refState.width, + event->button.y/(float)refState.height, 0, 0); #else SDLash_MouseEvent( event->button ); #endif @@ -289,13 +288,13 @@ static void SDLash_EventFilter( SDL_Event *event ) if( scale == 2 ) { - x /= (float)glState.width; - y /= (float)glState.height; - dx /= (float)glState.width; - dy /= (float)glState.height; + x /= (float)refState.width; + y /= (float)refState.height; + dx /= (float)refState.width; + dy /= (float)refState.height; } - IN_TouchEvent( type, event->tfinger.fingerId, x, y, dx, dy ); + // IN_TouchEvent( type, event->tfinger.fingerId, x, y, dx, dy ); break; } diff --git a/engine/platform/sdl/in_sdl.c b/engine/platform/sdl/in_sdl.c index 38363a7c..7d1de45b 100644 --- a/engine/platform/sdl/in_sdl.c +++ b/engine/platform/sdl/in_sdl.c @@ -23,7 +23,6 @@ GNU General Public License for more details. #include "events.h" #include "sound.h" #include "vid_common.h" -#include "gl_local.h" static SDL_Joystick *joy; static SDL_GameController *gamecontroller; diff --git a/engine/platform/sdl/vid_sdl.c b/engine/platform/sdl/vid_sdl.c index 80ba4e05..a602c326 100644 --- a/engine/platform/sdl/vid_sdl.c +++ b/engine/platform/sdl/vid_sdl.c @@ -16,7 +16,6 @@ GNU General Public License for more details. #include #include "common.h" #include "client.h" -#include "gl_local.h" #include "mod_local.h" #include "input.h" #include "vid_common.h" @@ -24,193 +23,11 @@ GNU General Public License for more details. static vidmode_t *vidmodes = NULL; static int num_vidmodes = 0; -static int context_flags = 0; -#define GL_CALL( x ) #x, (void**)&p##x -static dllfunc_t opengl_110funcs[] = -{ - { GL_CALL( glClearColor ) }, - { GL_CALL( glClear ) }, - { GL_CALL( glAlphaFunc ) }, - { GL_CALL( glBlendFunc ) }, - { GL_CALL( glCullFace ) }, - { GL_CALL( glDrawBuffer ) }, - { GL_CALL( glReadBuffer ) }, - { GL_CALL( glAccum ) }, - { GL_CALL( glEnable ) }, - { GL_CALL( glDisable ) }, - { GL_CALL( glEnableClientState ) }, - { GL_CALL( glDisableClientState ) }, - { GL_CALL( glGetBooleanv ) }, - { GL_CALL( glGetDoublev ) }, - { GL_CALL( glGetFloatv ) }, - { GL_CALL( glGetIntegerv ) }, - { GL_CALL( glGetError ) }, - { GL_CALL( glGetString ) }, - { GL_CALL( glFinish ) }, - { GL_CALL( glFlush ) }, - { GL_CALL( glClearDepth ) }, - { GL_CALL( glDepthFunc ) }, - { GL_CALL( glDepthMask ) }, - { GL_CALL( glDepthRange ) }, - { GL_CALL( glFrontFace ) }, - { GL_CALL( glDrawElements ) }, - { GL_CALL( glDrawArrays ) }, - { GL_CALL( glColorMask ) }, - { GL_CALL( glIndexPointer ) }, - { GL_CALL( glVertexPointer ) }, - { GL_CALL( glNormalPointer ) }, - { GL_CALL( glColorPointer ) }, - { GL_CALL( glTexCoordPointer ) }, - { GL_CALL( glArrayElement ) }, - { GL_CALL( glColor3f ) }, - { GL_CALL( glColor3fv ) }, - { GL_CALL( glColor4f ) }, - { GL_CALL( glColor4fv ) }, - { GL_CALL( glColor3ub ) }, - { GL_CALL( glColor4ub ) }, - { GL_CALL( glColor4ubv ) }, - { GL_CALL( glTexCoord1f ) }, - { GL_CALL( glTexCoord2f ) }, - { GL_CALL( glTexCoord3f ) }, - { GL_CALL( glTexCoord4f ) }, - { GL_CALL( glTexCoord1fv ) }, - { GL_CALL( glTexCoord2fv ) }, - { GL_CALL( glTexCoord3fv ) }, - { GL_CALL( glTexCoord4fv ) }, - { GL_CALL( glTexGenf ) }, - { GL_CALL( glTexGenfv ) }, - { GL_CALL( glTexGeni ) }, - { GL_CALL( glVertex2f ) }, - { GL_CALL( glVertex3f ) }, - { GL_CALL( glVertex3fv ) }, - { GL_CALL( glNormal3f ) }, - { GL_CALL( glNormal3fv ) }, - { GL_CALL( glBegin ) }, - { GL_CALL( glEnd ) }, - { GL_CALL( glLineWidth ) }, - { GL_CALL( glPointSize ) }, - { GL_CALL( glMatrixMode ) }, - { GL_CALL( glOrtho ) }, - { GL_CALL( glRasterPos2f ) }, - { GL_CALL( glFrustum ) }, - { GL_CALL( glViewport ) }, - { GL_CALL( glPushMatrix ) }, - { GL_CALL( glPopMatrix ) }, - { GL_CALL( glPushAttrib ) }, - { GL_CALL( glPopAttrib ) }, - { GL_CALL( glLoadIdentity ) }, - { GL_CALL( glLoadMatrixd ) }, - { GL_CALL( glLoadMatrixf ) }, - { GL_CALL( glMultMatrixd ) }, - { GL_CALL( glMultMatrixf ) }, - { GL_CALL( glRotated ) }, - { GL_CALL( glRotatef ) }, - { GL_CALL( glScaled ) }, - { GL_CALL( glScalef ) }, - { GL_CALL( glTranslated ) }, - { GL_CALL( glTranslatef ) }, - { GL_CALL( glReadPixels ) }, - { GL_CALL( glDrawPixels ) }, - { GL_CALL( glStencilFunc ) }, - { GL_CALL( glStencilMask ) }, - { GL_CALL( glStencilOp ) }, - { GL_CALL( glClearStencil ) }, - { GL_CALL( glIsEnabled ) }, - { GL_CALL( glIsList ) }, - { GL_CALL( glIsTexture ) }, - { GL_CALL( glTexEnvf ) }, - { GL_CALL( glTexEnvfv ) }, - { GL_CALL( glTexEnvi ) }, - { GL_CALL( glTexParameterf ) }, - { GL_CALL( glTexParameterfv ) }, - { GL_CALL( glTexParameteri ) }, - { GL_CALL( glHint ) }, - { GL_CALL( glPixelStoref ) }, - { GL_CALL( glPixelStorei ) }, - { GL_CALL( glGenTextures ) }, - { GL_CALL( glDeleteTextures ) }, - { GL_CALL( glBindTexture ) }, - { GL_CALL( glTexImage1D ) }, - { GL_CALL( glTexImage2D ) }, - { GL_CALL( glTexSubImage1D ) }, - { GL_CALL( glTexSubImage2D ) }, - { GL_CALL( glCopyTexImage1D ) }, - { GL_CALL( glCopyTexImage2D ) }, - { GL_CALL( glCopyTexSubImage1D ) }, - { GL_CALL( glCopyTexSubImage2D ) }, - { GL_CALL( glScissor ) }, - { GL_CALL( glGetTexImage ) }, - { GL_CALL( glGetTexEnviv ) }, - { GL_CALL( glPolygonOffset ) }, - { GL_CALL( glPolygonMode ) }, - { GL_CALL( glPolygonStipple ) }, - { GL_CALL( glClipPlane ) }, - { GL_CALL( glGetClipPlane ) }, - { GL_CALL( glShadeModel ) }, - { GL_CALL( glGetTexLevelParameteriv ) }, - { GL_CALL( glGetTexLevelParameterfv ) }, - { GL_CALL( glFogfv ) }, - { GL_CALL( glFogf ) }, - { GL_CALL( glFogi ) }, - { NULL , NULL } -}; - -static dllfunc_t debugoutputfuncs[] = -{ - { GL_CALL( glDebugMessageControlARB ) }, - { GL_CALL( glDebugMessageInsertARB ) }, - { GL_CALL( glDebugMessageCallbackARB ) }, - { GL_CALL( glGetDebugMessageLogARB ) }, - { NULL , NULL } -}; - -static dllfunc_t multitexturefuncs[] = -{ - { GL_CALL( glMultiTexCoord1f ) }, - { GL_CALL( glMultiTexCoord2f ) }, - { GL_CALL( glMultiTexCoord3f ) }, - { GL_CALL( glMultiTexCoord4f ) }, - { GL_CALL( glActiveTexture ) }, - { GL_CALL( glActiveTextureARB ) }, - { GL_CALL( glClientActiveTexture ) }, - { GL_CALL( glClientActiveTextureARB ) }, - { NULL , NULL } -}; - -static dllfunc_t texture3dextfuncs[] = -{ - { GL_CALL( glTexImage3D ) }, - { GL_CALL( glTexSubImage3D ) }, - { GL_CALL( glCopyTexSubImage3D ) }, - { NULL , NULL } -}; - -static dllfunc_t texturecompressionfuncs[] = -{ - { GL_CALL( glCompressedTexImage3DARB ) }, - { GL_CALL( glCompressedTexImage2DARB ) }, - { GL_CALL( glCompressedTexImage1DARB ) }, - { GL_CALL( glCompressedTexSubImage3DARB ) }, - { GL_CALL( glCompressedTexSubImage2DARB ) }, - { GL_CALL( glCompressedTexSubImage1DARB ) }, - { GL_CALL( glGetCompressedTexImage ) }, - { NULL , NULL } -}; - -static dllfunc_t vbofuncs[] = -{ - { GL_CALL( glBindBufferARB ) }, - { GL_CALL( glDeleteBuffersARB ) }, - { GL_CALL( glGenBuffersARB ) }, - { GL_CALL( glIsBufferARB ) }, - { GL_CALL( glMapBufferARB ) }, - { GL_CALL( glUnmapBufferARB ) }, // , - { GL_CALL( glBufferDataARB ) }, - { GL_CALL( glBufferSubDataARB ) }, - { NULL, NULL} -}; - static void GL_SetupAttributes( void ); +struct +{ + int prev_width, prev_height; +} sdlState; int R_MaxVideoModes( void ) { @@ -348,39 +165,6 @@ static void WIN_SetDPIAwareness( void ) } #endif -/* -======================== -DebugCallback - -For ARB_debug_output -======================== -*/ -static void APIENTRY GL_DebugOutput( GLuint source, GLuint type, GLuint id, GLuint severity, GLint length, const GLcharARB *message, GLvoid *userParam ) -{ - switch( type ) - { - case GL_DEBUG_TYPE_ERROR_ARB: - Con_Printf( S_OPENGL_ERROR "%s\n", message ); - break; - case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: - Con_Printf( S_OPENGL_WARN "%s\n", message ); - break; - case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: - Con_Printf( S_OPENGL_WARN "%s\n", message ); - break; - case GL_DEBUG_TYPE_PORTABILITY_ARB: - if( host_developer.value < DEV_EXTENDED ) - return; - Con_Printf( S_OPENGL_WARN "%s\n", message ); - break; - case GL_DEBUG_TYPE_PERFORMANCE_ARB: - Con_Printf( S_OPENGL_NOTE "%s\n", message ); - break; - case GL_DEBUG_TYPE_OTHER_ARB: - default: Con_Printf( S_OPENGL_NOTE "%s\n", message ); - break; - } -} /* ================= @@ -450,33 +234,13 @@ GL_CreateContext */ qboolean GL_CreateContext( void ) { - int colorBits[3]; -#ifdef XASH_NANOGL - nanoGL_Init(); -#endif - if( ( glw_state.context = SDL_GL_CreateContext( host.hWnd ) ) == NULL) { Con_Reportf( S_ERROR "GL_CreateContext: %s\n", SDL_GetError()); return GL_DeleteContext(); } - 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]; - - 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_MULTISAMPLESAMPLES, &glConfig.msaasamples ); - -#ifdef XASH_WES - void wes_init(); - wes_init(); -#endif + ref.dllFuncs.GL_OnContextCreated(); return true; } @@ -606,7 +370,7 @@ qboolean VID_CreateWindow( int width, int height, qboolean fullscreen ) if( !gl_wgl_msaa_samples->value && glw_state.safe + 1 == SAFE_NOMSAA ) glw_state.safe += 2; // no need to skip msaa, if we already disabled it else glw_state.safe++; - GL_SetupAttributes(); // re-choose attributes + GL_SetupAttributes( ); // re-choose attributes // try again return VID_CreateWindow( width, height, fullscreen ); @@ -710,9 +474,9 @@ void VID_DestroyWindow( void ) host.hWnd = NULL; } - if( glState.fullScreen ) + if( refState.fullScreen ) { - glState.fullScreen = false; + refState.fullScreen = false; } } @@ -723,131 +487,26 @@ GL_SetupAttributes */ static void GL_SetupAttributes( void ) { - int samples; - -#if !defined(_WIN32) - SDL_SetHint( "SDL_VIDEO_X11_XRANDR", "1" ); - SDL_SetHint( "SDL_VIDEO_X11_XVIDMODE", "1" ); -#endif - SDL_GL_ResetAttributes(); -#ifdef XASH_GLES - SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES ); - SDL_GL_SetAttribute( SDL_GL_CONTEXT_EGL, 1 ); -#ifdef XASH_NANOGL - SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 1 ); - SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 ); -#elif defined( XASH_WES ) || defined( XASH_REGAL ) - SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 2 ); - SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 0 ); -#endif -#else // GL1.x -#ifndef XASH_GL_STATIC - if( Sys_CheckParm( "-gldebug" ) ) - { - Con_Reportf( "Creating an extended GL context for debug...\n" ); - SetBits( context_flags, FCONTEXT_DEBUG_ARB ); - SDL_GL_SetAttribute( SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG ); - glw_state.extended = true; - } -#endif // XASH_GL_STATIC - if( Sys_CheckParm( "-glcore" )) - { - SetBits( context_flags, FCONTEXT_CORE_PROFILE ); + ref.dllFuncs.GL_SetupAttributes( glw_state.safe ); +} - SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE ); - } - else - { - SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY ); - } -#endif // XASH_GLES - if( glw_state.safe > SAFE_DONTCARE ) - { - glw_state.safe = -1; // can't retry anymore, can only shutdown engine - return; - } +void GL_SwapBuffers() +{ + SDL_GL_SwapWindow( host.hWnd ); +} - Msg( "Trying safe opengl mode %d\n", glw_state.safe ); - if( glw_state.safe == SAFE_DONTCARE ) - return; +int GL_SetAttribute( int attr, int val ) +{ + return SDL_GL_SetAttribute( (SDL_GLattr)attr, val ); +} - SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); - - if( glw_state.safe < SAFE_NOACC ) - SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 ); - - Msg( "bpp %d\n", glw_state.desktopBitsPixel ); - - 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 ); - - if( glw_state.safe < SAFE_NODEPTH ) - SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 ); - else - SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 8 ); - - if( glw_state.safe < SAFE_NOCOLOR ) - { - if( glw_state.desktopBitsPixel >= 24 ) - { - SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 ); - SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 ); - SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 ); - } - else if( glw_state.desktopBitsPixel >= 16 ) - { - SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 ); - SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 6 ); - SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 ); - } - else - { - SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 3 ); - SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 3 ); - SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 2 ); - } - } - - if( glw_state.safe < SAFE_NOMSAA ) - { - switch( (int)gl_wgl_msaa_samples->value ) - { - case 2: - case 4: - case 8: - case 16: - samples = gl_wgl_msaa_samples->value; - break; - default: - samples = 0; // don't use, because invalid parameter is passed - } - - if( samples ) - { - SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 ); - SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, samples ); - - glConfig.max_multisamples = samples; - } - else - { - SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 0 ); - SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, 0 ); - - glConfig.max_multisamples = 0; - } - } - else - { - Cvar_Set( "gl_wgl_msaa_samples", "0" ); - } +int GL_GetAttribute( int attr, int *val ) +{ + return SDL_GL_GetAttribute( (SDL_GLattr)attr, val ); } #ifndef EGL_LIB @@ -859,7 +518,7 @@ static void GL_SetupAttributes( void ) R_Init_Video ================== */ -qboolean R_Init_Video( void ) +qboolean R_Init_Video( const int type ) { SDL_DisplayMode displayMode; string safe; @@ -870,10 +529,21 @@ qboolean R_Init_Video( void ) glw_state.desktopWidth = displayMode.w; glw_state.desktopHeight = displayMode.h; + if( type != REF_GL ) + { + Host_Error( "Can't initialize unknown context type %d!\n", type ); + } + if( !glw_state.safe && Sys_GetParmFromCmdLine( "-safegl", safe ) ) glw_state.safe = bound( SAFE_NO, Q_atoi( safe ), SAFE_DONTCARE ); - GL_SetupAttributes(); +#if !defined(_WIN32) + SDL_SetHint( "SDL_VIDEO_X11_XRANDR", "1" ); + SDL_SetHint( "SDL_VIDEO_X11_XVIDMODE", "1" ); +#endif + + // refdll can request some attributes + GL_SetupAttributes( ); if( SDL_GL_LoadLibrary( EGL_LIB ) ) { @@ -893,255 +563,13 @@ qboolean R_Init_Video( void ) return retval; } - GL_InitExtensions(); + // refdll also can check extensions + ref.dllFuncs.GL_InitExtensions(); + + host.renderinfo_changed = false; return true; } -#ifdef XASH_GLES -void GL_InitExtensionsGLES( void ) -{ - // intialize wrapper type -#ifdef XASH_NANOGL - glConfig.context = CONTEXT_TYPE_GLES_1_X; - glConfig.wrapper = GLES_WRAPPER_NANOGL; -#elif defined( XASH_WES ) - glConfig.context = CONTEXT_TYPE_GLES_2_X; - glConfig.wrapper = GLES_WRAPPER_WES; -#endif - - glConfig.hardware_type = GLHW_GENERIC; - - // initalize until base opengl functions loaded - GL_SetExtension( GL_DRAW_RANGEELEMENTS_EXT, true ); - GL_SetExtension( GL_ARB_MULTITEXTURE, true ); - pglGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, &glConfig.max_texture_units ); - glConfig.max_texture_coords = glConfig.max_texture_units = 4; - - GL_SetExtension( GL_ENV_COMBINE_EXT, true ); - GL_SetExtension( GL_DOT3_ARB_EXT, true ); - GL_SetExtension( GL_TEXTURE_3D_EXT, false ); - GL_SetExtension( GL_SGIS_MIPMAPS_EXT, true ); // gles specs - GL_SetExtension( GL_ARB_VERTEX_BUFFER_OBJECT_EXT, true ); // gles specs - - // hardware cubemaps - GL_CheckExtension( "GL_OES_texture_cube_map", NULL, "gl_texture_cubemap", GL_TEXTURECUBEMAP_EXT ); - - if( GL_Support( GL_TEXTURECUBEMAP_EXT )) - pglGetIntegerv( GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, &glConfig.max_cubemap_size ); - - GL_SetExtension( GL_ARB_SEAMLESS_CUBEMAP, false ); - - GL_SetExtension( GL_EXT_POINTPARAMETERS, false ); - GL_CheckExtension( "GL_OES_texture_npot", NULL, "gl_texture_npot", GL_ARB_TEXTURE_NPOT_EXT ); - - GL_SetExtension( GL_TEXTURE_COMPRESSION_EXT, false ); - GL_SetExtension( GL_CUSTOM_VERTEX_ARRAY_EXT, false ); - GL_SetExtension( GL_CLAMPTOEDGE_EXT, true ); // by gles1 specs - GL_SetExtension( GL_ANISOTROPY_EXT, false ); - GL_SetExtension( GL_TEXTURE_LODBIAS, false ); - GL_SetExtension( GL_CLAMP_TEXBORDER_EXT, false ); - GL_SetExtension( GL_BLEND_MINMAX_EXT, false ); - GL_SetExtension( GL_BLEND_SUBTRACT_EXT, false ); - GL_SetExtension( GL_SEPARATESTENCIL_EXT, false ); - GL_SetExtension( GL_STENCILTWOSIDE_EXT, false ); - GL_SetExtension( GL_TEXTURE_ENV_ADD_EXT,false ); - GL_SetExtension( GL_SHADER_OBJECTS_EXT, false ); - GL_SetExtension( GL_SHADER_GLSL100_EXT, false ); - GL_SetExtension( GL_VERTEX_SHADER_EXT,false ); - GL_SetExtension( GL_FRAGMENT_SHADER_EXT, false ); - GL_SetExtension( GL_SHADOW_EXT, false ); - GL_SetExtension( GL_ARB_DEPTH_FLOAT_EXT, false ); - GL_SetExtension( GL_OCCLUSION_QUERIES_EXT,false ); - GL_CheckExtension( "GL_OES_depth_texture", NULL, "gl_depthtexture", GL_DEPTH_TEXTURE ); - - glConfig.texRectangle = glConfig.max_2d_rectangle_size = 0; // no rectangle - - Cvar_FullSet( "gl_allow_mirrors", "0", CVAR_READ_ONLY); // No support for GLES - -} -#else -void GL_InitExtensionsBigGL() -{ - // intialize wrapper type - glConfig.context = CONTEXT_TYPE_GL; - glConfig.wrapper = GLES_WRAPPER_NONE; - - if( Q_stristr( glConfig.renderer_string, "geforce" )) - glConfig.hardware_type = GLHW_NVIDIA; - else if( Q_stristr( glConfig.renderer_string, "quadro fx" )) - glConfig.hardware_type = GLHW_NVIDIA; - else if( Q_stristr(glConfig.renderer_string, "rv770" )) - glConfig.hardware_type = GLHW_RADEON; - else if( Q_stristr(glConfig.renderer_string, "radeon hd" )) - glConfig.hardware_type = GLHW_RADEON; - else if( Q_stristr( glConfig.renderer_string, "eah4850" ) || Q_stristr( glConfig.renderer_string, "eah4870" )) - glConfig.hardware_type = GLHW_RADEON; - else if( Q_stristr( glConfig.renderer_string, "radeon" )) - glConfig.hardware_type = GLHW_RADEON; - else if( Q_stristr( glConfig.renderer_string, "intel" )) - glConfig.hardware_type = GLHW_INTEL; - else glConfig.hardware_type = GLHW_GENERIC; - - // multitexture - glConfig.max_texture_units = glConfig.max_texture_coords = glConfig.max_teximage_units = 1; - GL_CheckExtension( "GL_ARB_multitexture", multitexturefuncs, "gl_arb_multitexture", GL_ARB_MULTITEXTURE ); - - if( GL_Support( GL_ARB_MULTITEXTURE )) - { - pglGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, &glConfig.max_texture_units ); - } - - if( glConfig.max_texture_units == 1 ) - GL_SetExtension( GL_ARB_MULTITEXTURE, false ); - - // 3d texture support - GL_CheckExtension( "GL_EXT_texture3D", texture3dextfuncs, "gl_texture_3d", GL_TEXTURE_3D_EXT ); - - if( GL_Support( GL_TEXTURE_3D_EXT )) - { - pglGetIntegerv( GL_MAX_3D_TEXTURE_SIZE, &glConfig.max_3d_texture_size ); - - if( glConfig.max_3d_texture_size < 32 ) - { - GL_SetExtension( GL_TEXTURE_3D_EXT, false ); - Con_Printf( S_ERROR "GL_EXT_texture3D reported bogus GL_MAX_3D_TEXTURE_SIZE, disabled\n" ); - } - } - - // 2d texture array support - GL_CheckExtension( "GL_EXT_texture_array", texture3dextfuncs, "gl_texture_2d_array", GL_TEXTURE_ARRAY_EXT ); - - if( GL_Support( GL_TEXTURE_ARRAY_EXT )) - pglGetIntegerv( GL_MAX_ARRAY_TEXTURE_LAYERS_EXT, &glConfig.max_2d_texture_layers ); - - // cubemaps support - GL_CheckExtension( "GL_ARB_texture_cube_map", NULL, "gl_texture_cubemap", GL_TEXTURE_CUBEMAP_EXT ); - - if( GL_Support( GL_TEXTURE_CUBEMAP_EXT )) - { - pglGetIntegerv( GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, &glConfig.max_cubemap_size ); - - // check for seamless cubemaps too - GL_CheckExtension( "GL_ARB_seamless_cube_map", NULL, "gl_texture_cubemap_seamless", GL_ARB_SEAMLESS_CUBEMAP ); - } - - GL_CheckExtension( "GL_ARB_texture_non_power_of_two", NULL, "gl_texture_npot", GL_ARB_TEXTURE_NPOT_EXT ); - GL_CheckExtension( "GL_ARB_texture_compression", texturecompressionfuncs, "gl_dds_hardware_support", GL_TEXTURE_COMPRESSION_EXT ); - GL_CheckExtension( "GL_EXT_texture_edge_clamp", NULL, "gl_clamp_to_edge", GL_CLAMPTOEDGE_EXT ); - if( !GL_Support( GL_CLAMPTOEDGE_EXT )) - GL_CheckExtension( "GL_SGIS_texture_edge_clamp", NULL, "gl_clamp_to_edge", GL_CLAMPTOEDGE_EXT ); - - glConfig.max_texture_anisotropy = 0.0f; - GL_CheckExtension( "GL_EXT_texture_filter_anisotropic", NULL, "gl_ext_anisotropic_filter", GL_ANISOTROPY_EXT ); - if( GL_Support( GL_ANISOTROPY_EXT )) - pglGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.max_texture_anisotropy ); - -#ifdef _WIN32 // Win32 only drivers? - // g-cont. because lodbias it too glitchy on Intel's cards - if( glConfig.hardware_type != GLHW_INTEL ) -#endif - GL_CheckExtension( "GL_EXT_texture_lod_bias", NULL, "gl_texture_mipmap_biasing", GL_TEXTURE_LOD_BIAS ); - - if( GL_Support( GL_TEXTURE_LOD_BIAS )) - pglGetFloatv( GL_MAX_TEXTURE_LOD_BIAS_EXT, &glConfig.max_texture_lod_bias ); - - GL_CheckExtension( "GL_ARB_texture_border_clamp", NULL, "gl_ext_texborder_clamp", GL_CLAMP_TEXBORDER_EXT ); - GL_CheckExtension( "GL_ARB_depth_texture", NULL, "gl_depthtexture", GL_DEPTH_TEXTURE ); - GL_CheckExtension( "GL_ARB_texture_float", NULL, "gl_arb_texture_float", GL_ARB_TEXTURE_FLOAT_EXT ); - GL_CheckExtension( "GL_ARB_depth_buffer_float", NULL, "gl_arb_depth_float", GL_ARB_DEPTH_FLOAT_EXT ); - GL_CheckExtension( "GL_EXT_gpu_shader4", NULL, NULL, GL_EXT_GPU_SHADER4 ); // don't confuse users - GL_CheckExtension( "GL_ARB_shading_language_100", NULL, "gl_glslprogram", GL_SHADER_GLSL100_EXT ); - GL_CheckExtension( "GL_ARB_vertex_buffer_object", vbofuncs, "gl_vertex_buffer_object", GL_ARB_VERTEX_BUFFER_OBJECT_EXT ); - - // rectangle textures support - GL_CheckExtension( "GL_ARB_texture_rectangle", NULL, "gl_texture_rectangle", GL_TEXTURE_2D_RECT_EXT ); - - // this won't work without extended context - if( glw_state.extended ) - GL_CheckExtension( "GL_ARB_debug_output", debugoutputfuncs, "gl_debug_output", GL_DEBUG_OUTPUT ); - - if( GL_Support( GL_SHADER_GLSL100_EXT )) - { - pglGetIntegerv( GL_MAX_TEXTURE_COORDS_ARB, &glConfig.max_texture_coords ); - pglGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &glConfig.max_teximage_units ); - - // check for hardware skinning - pglGetIntegerv( GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &glConfig.max_vertex_uniforms ); - pglGetIntegerv( GL_MAX_VERTEX_ATTRIBS_ARB, &glConfig.max_vertex_attribs ); - -#ifdef _WIN32 // Win32 only drivers? - if( glConfig.hardware_type == GLHW_RADEON && glConfig.max_vertex_uniforms > 512 ) - glConfig.max_vertex_uniforms /= 4; // radeon returns not correct info -#endif - } - else - { - // just get from multitexturing - glConfig.max_texture_coords = glConfig.max_teximage_units = glConfig.max_texture_units; - } - - pglGetIntegerv( GL_MAX_TEXTURE_SIZE, &glConfig.max_2d_texture_size ); - if( glConfig.max_2d_texture_size <= 0 ) glConfig.max_2d_texture_size = 256; - - if( GL_Support( GL_TEXTURE_2D_RECT_EXT )) - pglGetIntegerv( GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT, &glConfig.max_2d_rectangle_size ); - -#ifndef XASH_GL_STATIC - // enable gldebug if allowed - if( GL_Support( GL_DEBUG_OUTPUT )) - { - if( host_developer.value ) - { - Con_Reportf( "Installing GL_DebugOutput...\n"); - pglDebugMessageCallbackARB( GL_DebugOutput, NULL ); - - // force everything to happen in the main thread instead of in a separate driver thread - pglEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB ); - } - - // enable all the low priority messages - pglDebugMessageControlARB( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, true ); - } -#endif -} -#endif - -void GL_InitExtensions( void ) -{ - // initialize gl extensions - GL_CheckExtension( "OpenGL 1.1.0", opengl_110funcs, NULL, GL_OPENGL_110 ); - - // get our various GL strings - glConfig.vendor_string = pglGetString( GL_VENDOR ); - glConfig.renderer_string = pglGetString( GL_RENDERER ); - glConfig.version_string = pglGetString( GL_VERSION ); - glConfig.extensions_string = pglGetString( GL_EXTENSIONS ); - Con_Reportf( "^3Video^7: %s\n", glConfig.renderer_string ); - -#ifdef XASH_GLES - GL_InitExtensionsGLES(); -#else - GL_InitExtensionsBigGL(); -#endif - - if( GL_Support( GL_TEXTURE_2D_RECT_EXT )) - pglGetIntegerv( GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT, &glConfig.max_2d_rectangle_size ); - - Cvar_Get( "gl_max_size", va( "%i", glConfig.max_2d_texture_size ), 0, "opengl texture max dims" ); - Cvar_Set( "gl_anisotropy", va( "%f", bound( 0, gl_texture_anisotropy->value, glConfig.max_texture_anisotropy ))); - - if( GL_Support( GL_TEXTURE_COMPRESSION_EXT )) - Image_AddCmdFlags( IL_DDS_HARDWARE ); - - // MCD has buffering issues -#ifdef _WIN32 - if( Q_strstr( glConfig.renderer_string, "gdi" )) - Cvar_SetValue( "gl_finish", 1 ); -#endif - - tr.framecount = tr.visframecount = 1; - glw_state.initialized = true; -} rserr_t R_ChangeDisplaySettings( int width, int height, qboolean fullscreen ) { @@ -1156,7 +584,7 @@ rserr_t R_ChangeDisplaySettings( int width, int height, qboolean fullscreen ) glw_state.desktopWidth = displayMode.w; glw_state.desktopHeight = displayMode.h; - glState.fullScreen = fullscreen; + refState.fullScreen = fullscreen; if( !host.hWnd ) { @@ -1228,8 +656,8 @@ qboolean VID_SetMode( void ) if(( err = R_ChangeDisplaySettings( iScreenWidth, iScreenHeight, fullscreen )) == rserr_ok ) { - glConfig.prev_width = iScreenWidth; - glConfig.prev_height = iScreenHeight; + sdlState.prev_width = iScreenWidth; + sdlState.prev_height = iScreenHeight; } else { @@ -1248,7 +676,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( sdlState.prev_width, sdlState.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!"); @@ -1271,9 +699,7 @@ void R_Free_Video( void ) R_FreeVideoModes(); - // now all extensions are disabled - memset( glConfig.extension, 0, sizeof( glConfig.extension )); - glw_state.initialized = false; + ref.dllFuncs.GL_ClearExtensions(); } #endif // XASH_DEDICATED diff --git a/engine/ref_api.h b/engine/ref_api.h new file mode 100644 index 00000000..29046dca --- /dev/null +++ b/engine/ref_api.h @@ -0,0 +1,626 @@ +/* +ref_api.h - Xash3D render dll API +Copyright (C) 2019 a1batross + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ +#pragma once +#ifndef REF_API +#define REF_API + +#include +#include "com_image.h" +#include "vgui_api.h" +#include "render_api.h" +#include "triangleapi.h" +#include "const.h" +#include "cl_entity.h" +#include "com_model.h" +#include "studio.h" +#include "r_efx.h" +#include "com_image.h" + +#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) + +#define FCONTEXT_CORE_PROFILE BIT( 0 ) +#define FCONTEXT_DEBUG_ARB BIT( 1 ) + +#define FCVAR_RENDERINFO (1<<16) // save to a seperate config called video.cfg +#define FCVAR_READ_ONLY (1<<17) // cannot be set by user at all, and can't be requested by CvarGetPointer from game dlls + +// 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 + +// model flags (stored in model_t->flags) +#define MODEL_CONVEYOR BIT( 0 ) +#define MODEL_HAS_ORIGIN BIT( 1 ) +#define MODEL_LIQUID BIT( 2 ) // model has only point hull +#define MODEL_TRANSPARENT BIT( 3 ) // have transparent surfaces +#define MODEL_COLORED_LIGHTING BIT( 4 ) // lightmaps stored as RGB +#define MODEL_WORLD BIT( 29 ) // it's a worldmodel +#define MODEL_CLIENT BIT( 30 ) // client sprite + +// goes into world.flags +#define FWORLD_SKYSPHERE BIT( 0 ) +#define FWORLD_CUSTOM_SKYBOX BIT( 1 ) +#define FWORLD_WATERALPHA BIT( 2 ) +#define FWORLD_HAS_DELUXEMAP BIT( 3 ) + +typedef enum +{ + DEMO_INACTIVE = 0, + DEMO_XASH3D, + DEMO_QUAKE1 +} demo_mode; + +typedef struct +{ + msurface_t *surf; + int cull; +} sortedface_t; + +typedef struct ref_globals_s +{ + qboolean developer; + + float time; // cl.time + float oldtime; // cl.oldtime + double realtime; // host.realtime + double frametime; // host.frametime + + // viewport width and height + int width; + int height; + qboolean fullScreen; + qboolean wideScreen; + + vec3_t vieworg; + vec3_t viewangles; + vec3_t vforward, vright, vup; + + cl_entity_t *currententity; + model_t *currentmodel; + + float fov_x, fov_y; + + // todo: fill this without engine help + // move to local + + // translucent sorted array + sortedface_t *draw_surfaces; // used for sorting translucent surfaces + int max_surfaces; // max surfaces per submodel (for all models) + size_t visbytes; // cluster size +} ref_globals_t; + +enum +{ + GL_KEEP_UNIT = -1, + XASH_TEXTURE0 = 0, + XASH_TEXTURE1, + XASH_TEXTURE2, + XASH_TEXTURE3, // g-cont. 4 units should be enough + XASH_TEXTURE4, // mittorn. bump+detail needs 5 for single-pass + MAX_TEXTURE_UNITS = 32 // can't access to all over units without GLSL or cg +}; + +enum // r_speeds counters +{ + RS_ACTIVE_TENTS = 0, +}; + +enum ref_shared_texture_e +{ + REF_DEFAULT_TEXTURE, + REF_GRAY_TEXTURE, + REF_WHITE_TEXTURE, + REF_SOLIDSKY_TEXTURE, + REF_ALPHASKY_TEXTURE, +}; + +typedef enum connstate_e +{ + ca_disconnected = 0,// not talking to a server + ca_connecting, // sending request packets to the server + ca_connected, // netchan_t established, waiting for svc_serverdata + ca_validate, // download resources, validating, auth on server + ca_active, // game views should be displayed + ca_cinematic, // playing a cinematic, not connected to a server +} connstate_t; + +enum ref_defaultsprite_e +{ + REF_DOT_SPRITE, // cl_sprite_dot + REF_CHROME_SPRITE // cl_sprite_shell +}; + +enum ref_graphic_apis_e +{ + REF_SOFTWARE, // hypothetical: just make a surface to draw on, in software + REF_GL, // create GL context +}; + +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 +} ref_safegl_context_t; + +// binary compatible with SDL2 +enum // OpenGL configuration attributes +{ + REF_GL_RED_SIZE, + REF_GL_GREEN_SIZE, + REF_GL_BLUE_SIZE, + REF_GL_ALPHA_SIZE, + REF_GL_BUFFER_SIZE, + REF_GL_DOUBLEBUFFER, + REF_GL_DEPTH_SIZE, + REF_GL_STENCIL_SIZE, + REF_GL_ACCUM_RED_SIZE, + REF_GL_ACCUM_GREEN_SIZE, + REF_GL_ACCUM_BLUE_SIZE, + REF_GL_ACCUM_ALPHA_SIZE, + REF_GL_STEREO, + REF_GL_MULTISAMPLEBUFFERS, + REF_GL_MULTISAMPLESAMPLES, + REF_GL_ACCELERATED_VISUAL, + REF_GL_RETAINED_BACKING, + REF_GL_CONTEXT_MAJOR_VERSION, + REF_GL_CONTEXT_MINOR_VERSION, + REF_GL_CONTEXT_EGL, + REF_GL_CONTEXT_FLAGS, + REF_GL_CONTEXT_PROFILE_MASK, + REF_GL_SHARE_WITH_CURRENT_CONTEXT, + REF_GL_FRAMEBUFFER_SRGB_CAPABLE, + REF_GL_CONTEXT_RELEASE_BEHAVIOR, + REF_GL_CONTEXT_RESET_NOTIFICATION, + REF_GL_CONTEXT_NO_ERROR +}; + +enum +{ + REF_GL_CONTEXT_PROFILE_CORE = 0x0001, + REF_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002, + REF_GL_CONTEXT_PROFILE_ES = 0x0004 /**< GLX_CONTEXT_ES2_PROFILE_BIT_EXT */ +}; + +enum +{ + REF_GL_CONTEXT_DEBUG_FLAG = 0x0001, + REF_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002, + REF_GL_CONTEXT_ROBUST_ACCESS_FLAG = 0x0004, + REF_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008 +}; + +typedef struct remap_info_s +{ + unsigned short textures[MAX_SKINS];// alias textures + struct mstudiotex_s *ptexture; // array of textures with local copy of remapped textures + short numtextures; // textures count + short topcolor; // cached value + short bottomcolor; // cached value + model_t *model; // for catch model changes +} remap_info_t; + +struct con_nprint_s; +struct engine_studio_api_s; +struct r_studio_interface_s; + +typedef enum +{ + PARM_DEV_OVERVIEW = -1, + PARM_THIRDPERSON = -2, + PARM_QUAKE_COMPATIBLE = -3, + PARM_PLAYER_INDEX = -4, // cl.playernum + 1 + PARM_VIEWENT_INDEX = -5, // cl.viewentity + PARM_CONNSTATE = -6, // cls.state + PARM_PLAYING_DEMO = -7, // cls.demoplayback + PARM_WATER_LEVEL = -8, // cl.local.water_level + PARM_MAX_CLIENTS = -9, // cl.maxclients + PARM_LOCAL_HEALTH = -10, // cl.local.health + PARM_LOCAL_GAME = -11, + PARM_NUMENTITIES = -12, // local game only + PARM_NUMMODELS = -13, // cl.nummodels +} ref_parm_e; + +typedef struct ref_api_s +{ + int (*EngineGetParm)( int parm, int arg ); // generic + + // cvar handlers + cvar_t *(*Cvar_Get)( const char *szName, const char *szValue, int flags, const char *description ); + cvar_t *(*pfnGetCvarPointer)( const char *name, int ignore_flags ); + float (*pfnGetCvarFloat)( const char *szName ); + const char *(*pfnGetCvarString)( const char *szName ); + void (*Cvar_SetValue)( const char *name, float value ); + void (*Cvar_Set)( const char *name, const char *value ); + void (*Cvar_RegisterVariable)( cvar_t *var ); + void (*Cvar_FullSet)( const char *var_name, const char *value, int flags ); + + // command handlers + int (*Cmd_AddCommand)( const char *cmd_name, void (*function)(void), const char *description ); + void (*Cmd_RemoveCommand)( const char *cmd_name ); + int (*Cmd_Argc)( void ); + const char *(*Cmd_Argv)( int arg ); + const char *(*Cmd_Args)( void ); + + // cbuf + void (*Cbuf_AddText)( const char *commands ); + void (*Cbuf_InsertText)( const char *commands ); + void (*Cbuf_Execute)( void ); + void (*Cbuf_SetOpenGLConfigHack)( qboolean set ); // host.apply_opengl_config + + // logging + void (*Con_Printf)( const char *fmt, ... ); // typical console allowed messages + void (*Con_DPrintf)( const char *fmt, ... ); // -dev 1 + void (*Con_Reportf)( const char *fmt, ... ); // -dev 2 + + // debug print + void (*Con_NPrintf)( int pos, const char *fmt, ... ); + void (*Con_NXPrintf)( struct con_nprint_s *info, const char *fmt, ... ); + void (*CL_CenterPrint)( const char *s, float y ); + void (*Con_DrawStringLen)( const char *pText, int *length, int *height ); + int (*Con_DrawString)( int x, int y, const char *string, rgba_t setColor ); + void (*CL_DrawCenterPrint)(); + + // entity management + struct cl_entity_s *(*GetLocalPlayer)( void ); + struct cl_entity_s *(*GetViewModel)( void ); + struct cl_entity_s *(*GetEntityByIndex)( int idx ); + struct cl_entity_s *(*R_BeamGetEntity)( int index ); + struct cl_entity_s *(*CL_GetWaterEntity)( vec3_t p ); + qboolean (*CL_AddVisibleEntity)( cl_entity_t *ent, int entityType ); + + // brushes + int (*Mod_SampleSizeForFace)( struct msurface_s *surf ); + qboolean (*Mod_BoxVisible)( const vec3_t mins, const vec3_t maxs, const byte *visbits ); + struct world_static_s *(*GetWorld)( void ); // returns &world + mleaf_t *(*Mod_PointInLeaf)( const vec3_t p, mnode_t *node ); + void (*Mod_CreatePolygonsForHull)( int hullnum ); + + // studio models + void (*R_StudioSlerpBones)( int numbones, vec4_t q1[], float pos1[][3], vec4_t q2[], float pos2[][3], float s ); + void (*R_StudioCalcBoneQuaternion)( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, vec4_t q ); + void (*R_StudioCalcBonePosition)( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, vec3_t adj, vec3_t pos ); + void *(*R_StudioGetAnim)( studiohdr_t *m_pStudioHeader, model_t *m_pSubModel, mstudioseqdesc_t *pseqdesc ); + void (*pfnStudioEvent)( const struct mstudioevent_s *event, const cl_entity_t *entity ); + + // efx + void (*CL_DrawEFX)( float time, qboolean fTrans ); + void (*CL_ThinkParticle)( double frametime, particle_t *p ); + void (*R_FreeDeadParticles)( particle_t **ppparticles ); + particle_t *(*CL_AllocParticleFast)( void ); // unconditionally give new particle pointer from cl_free_particles + struct dlight_s *(*CL_AllocElight)( int key ); + struct model_s *(*GetDefaultSprite)( enum ref_defaultsprite_e spr ); + void (*R_StoreEfrags)( struct efrag_s **ppefrag, int framecount );// store efrags for static entities + + // model management + model_t *(*Mod_ForName)( const char *name, qboolean crash, qboolean trackCRC ); + void *(*Mod_Extradata)( int type, model_t *model ); + struct model_s *(*pfnGetModelByIndex)( int index ); // CL_ModelHandle + struct model_s *(*Mod_GetCurrentLoadingModel)( void ); // loadmodel + void (*Mod_SetCurrentLoadingModel)( struct model_s* ); // loadmodel + + // remap + struct remap_info_s *(*CL_GetRemapInfoForEntity)( cl_entity_t *e ); + void (*CL_AllocRemapInfo)( int topcolor, int bottomcolor ); + void (*CL_FreeRemapInfo)( struct remap_info_s *info ); + void (*CL_UpdateRemapInfo)( int topcolor, int bottomcolor ); + + // utils + void (*CL_ExtraUpdate)( void ); + uint (*COM_HashKey)( const char *strings, uint hashSize ); + void (*Host_Error)( const char *fmt, ... ); + int (*CL_FxBlend)( cl_entity_t *e ); + void (*COM_SetRandomSeed)( int lSeed ); + float (*COM_RandomFloat)( float rmin, float rmax ); + int (*COM_RandomLong)( int rmin, int rmax ); + struct screenfade_s *(*GetScreenFade)( void ); + struct client_textmessage_s *(*pfnTextMessageGet)( const char *pName ); + void (*GetPredictedOrigin)( vec3_t v ); + byte *(*CL_GetPaletteColor)(int color); // clgame.palette[color] + void (*CL_GetScreenInfo)( int *width, int *height ); // clgame.scrInfo, ptrs may be NULL + void (*SetLocalLightLevel)( int level ); // cl.local.light_level + int (*Sys_CheckParm)( const char *flag ); + + // studio interface + player_info_t *(*pfnPlayerInfo)( int index ); + entity_state_t *(*pfnGetPlayerState)( int index ); + void *(*Mod_CacheCheck)( struct cache_user_s *c ); + void (*Mod_LoadCacheFile)( const char *path, struct cache_user_s *cu ); + void *(*Mod_Calloc)( int number, size_t size ); + int (*pfnGetStudioModelInterface)( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio ); + + // memory + byte *(*_Mem_AllocPool)( const char *name, const char *filename, int fileline ); + void (*_Mem_FreePool)( byte **poolptr, const char *filename, int fileline ); + void *(*_Mem_Alloc)( byte *poolptr, size_t size, qboolean clear, const char *filename, int fileline ); + void *(*_Mem_Realloc)( byte *poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline ); + void (*_Mem_Free)( void *data, const char *filename, int fileline ); + + // library management + void *(*COM_LoadLibrary)( const char *name, int build_ordinals_table, qboolean directpath ); + void (*COM_FreeLibrary)( void *handle ); + void *(*COM_GetProcAddress)( void *handle, const char *name ); + + // filesystem + byte* (*COM_LoadFile)( const char *path, fs_offset_t *pLength, qboolean gamedironly ); + char* (*COM_ParseFile)( char *data, char *token ); + // use Mem_Free instead + // void (*COM_FreeFile)( void *buffer ); + int (*FS_FileExists)( const char *filename, int gamedironly ); + void (*FS_AllowDirectPaths)( qboolean enable ); + + // video init + // try to create window + // will call GL_SetupAttributes in case of REF_GL + int (*R_Init_Video)( int type ); + void (*R_Free_Video)( void ); + + // GL + int (*GL_SetAttribute)( int attr, int value ); + int (*GL_GetAttribute)( int attr, int *value ); + void *(*GL_GetProcAddress)( const char *name ); + void (*GL_SwapBuffers)(); + + // gamma + void (*BuildGammaTable)( float lightgamma, float brightness ); + byte (*LightToTexGamma)( byte color ); // software gamma support + + // renderapi + lightstyle_t* (*GetLightStyle)( int number ); + dlight_t* (*GetDynamicLight)( int number ); + dlight_t* (*GetEntityLight)( int number ); + int (*R_FatPVS)( const float *org, float radius, byte *visbuffer, qboolean merge, qboolean fullvis ); + const struct ref_overview_s *( *GetOverviewParms )( void ); + double (*pfnTime)( void ); // Sys_DoubleTime + + // event api + struct physent_s *(*EV_GetPhysent)( int idx ); + struct msurface_s *( *EV_TraceSurface )( int ground, float *vstart, float *vend ); + struct pmtrace_s *(*PM_TraceLine)( float *start, float *end, int flags, int usehull, int ignore_pe ); + struct pmtrace_s *(*EV_VisTraceLine )( float *start, float *end, int flags ); + struct pmtrace_s (*CL_TraceLine)( vec3_t start, vec3_t end, int flags ); + struct movevars_s *(*pfnGetMoveVars)( void ); + + // imagelib + void (*Image_AddCmdFlags)( uint flags ); // used to check if hardware dxt is supported + void (*Image_SetForceFlags)( uint flags ); + void (*Image_ClearForceFlags)( void ); + qboolean (*Image_CustomPalette)( void ); + qboolean (*Image_Process)( rgbdata_t **pix, int width, int height, uint flags, float bumpscale ); + rgbdata_t *(*FS_LoadImage)( const char *filename, const byte *buffer, size_t size ); + qboolean (*FS_SaveImage)( const char *filename, rgbdata_t *pix ); + rgbdata_t *(*FS_CopyImage)( rgbdata_t *in ); + void (*FS_FreeImage)( rgbdata_t *pack ); + void (*Image_SetMDLPointer)( byte *p ); + byte *(*Image_GetPool)( void ); + const struct bpc_desc_s *(*Image_GetPFDesc)( int idx ); + + // client exports + void (*pfnDrawNormalTriangles)( void ); + void (*pfnDrawTransparentTriangles)( void ); + render_interface_t *drawFuncs; +} ref_api_t; + +struct mip_s; + +// render callbacks +typedef struct ref_interface_s +{ + // construct, destruct + qboolean (*R_Init)( void ); // context is true if you need context management + // const char *(*R_GetInitError)( void ); + void (*R_Shutdown)( void ); + + // + void (*GL_SetupAttributes)( int safegl ); + void (*GL_OnContextCreated)( void ); + void (*GL_InitExtensions)( void ); + void (*GL_ClearExtensions)( void ); + + + void (*R_BeginFrame)( qboolean clearScene ); + void (*R_RenderScene)( void ); + void (*R_EndFrame)( void ); + void (*R_PushScene)( void ); + void (*R_PopScene)( void ); + void (*GL_BackendStartFrame)( void ); + void (*GL_BackendEndFrame)( void ); + + void (*R_ClearScreen)( void ); // clears color buffer on GL + void (*R_AllowFog)( qboolean allow ); + void (*GL_SetRenderMode)( int renderMode ); + + qboolean (*R_AddEntity)( struct cl_entity_s *clent, int type ); + void (*CL_AddCustomBeam)( cl_entity_t *pEnvBeam ); + void (*R_ProcessEntData)( qboolean allocate ); + + // view info + qboolean (*IsNormalPass)( void ); + + // debug + void (*R_ShowTextures)( void ); + void (*R_ShowTree)( void ); + void (*R_IncrementSpeedsCounter)( int counterType ); + + // texture management + const byte *(*R_GetTextureOriginalBuffer)( unsigned int idx ); // not always available + int (*GL_LoadTextureFromBuffer)( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update ); + int (*R_GetBuiltinTexture)( enum ref_shared_texture_e type ); + void (*R_FreeSharedTexture)( enum ref_shared_texture_e type ); + void (*GL_ProcessTexture)( int texnum, float gamma, int topColor, int bottomColor ); + void (*R_SetupSky)( const char *skyname ); + + + // 2D + void (*R_Set2DMode)( qboolean enable ); + void (*R_DrawStretchRaw)( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty ); + void (*R_DrawStretchPic)( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum ); + void (*R_DrawTileClear)( int texnum, int x, int y, int w, int h ); + void (*FillRGBA)( float x, float y, float w, float h, int r, int g, int b, int a ); // in screen space + void (*FillRGBABlend)( float x, float y, float w, float h, int r, int g, int b, int a ); // in screen space + + // screenshot, cubemapshot + qboolean (*VID_ScreenShot)( const char *filename, int shot_type ); + qboolean (*VID_CubemapShot)( const char *base, uint size, const float *vieworg, qboolean skyshot ); + + // light + colorVec (*R_LightPoint)( const float *p ); + + // decals + // Shoots a decal onto the surface of the BSP. position is the center of the decal in world coords + void (*R_DecalShoot)( int textureIndex, int entityIndex, int modelIndex, vec3_t pos, int flags, float scale ); + void (*R_DecalRemoveAll)( int texture ); + int (*R_CreateDecalList)( struct decallist_s *pList ); + void (*R_ClearAllDecals)( void ); + + // 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 ); + int (*R_GetSpriteTexture)( const model_t *m_pSpriteModel, int frame ); + + // model management + // flags ignored for everything except spritemodels + void (*Mod_LoadMapSprite)( struct model_s *mod, const void *buffer, size_t size, qboolean *loaded ); + qboolean (*Mod_ProcessRenderData)( model_t *mod, qboolean create, const byte *buffer ); + void (*Mod_StudioLoadTextures)( model_t *mod, void *data ); + + // efx implementation + void (*CL_DrawParticles)( double frametime, particle_t *particles, float partsize ); + 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 + // Get renderer info (doesn't changes engine state at all) + int (*RefGetParm)( int parm, int arg ); // generic + void (*GetDetailScaleForTexture)( int texture, float *xScale, float *yScale ); + void (*GetExtraParmsForTexture)( int texture, byte *red, byte *green, byte *blue, byte *alpha ); + float (*GetFrameTime)( void ); + + // Set renderer info (tell engine about changes) + void (*R_SetCurrentEntity)( struct cl_entity_s *ent ); // tell engine about both currententity and currentmodel + void (*R_SetCurrentModel)( struct model_s *mod ); // change currentmodel but leave currententity unchanged + + // Texture tools + int (*GL_FindTexture)( const char *name ); + const char* (*GL_TextureName)( unsigned int texnum ); + const byte* (*GL_TextureData)( unsigned int texnum ); // may be NULL + int (*GL_LoadTexture)( const char *name, const byte *buf, size_t size, int flags ); + int (*GL_CreateTexture)( const char *name, int width, int height, const void *buffer, texFlags_t flags ); + int (*GL_LoadTextureArray)( const char **names, int flags ); + int (*GL_CreateTextureArray)( const char *name, int width, int height, int depth, const void *buffer, texFlags_t flags ); + void (*GL_FreeTexture)( unsigned int texnum ); + + // Decals manipulating (draw & remove) + void (*DrawSingleDecal)( struct decal_s *pDecal, struct msurface_s *fa ); + float *(*R_DecalSetupVerts)( struct decal_s *pDecal, struct msurface_s *surf, int texture, int *outCount ); + void (*R_EntityRemoveDecals)( struct model_s *mod ); // remove all the decals from specified entity (BSP only) + + // AVI + void (*AVI_UploadRawFrame)( int texture, int cols, int rows, int width, int height, const byte *data ); + + // glState related calls (must use this instead of normal gl-calls to prevent de-synchornize local states between engine and the client) + void (*GL_Bind)( int tmu, unsigned int texnum ); + void (*GL_SelectTexture)( int tmu ); + void (*GL_LoadTextureMatrix)( const float *glmatrix ); + void (*GL_TexMatrixIdentity)( void ); + void (*GL_CleanUpTextureUnits)( int last ); // pass 0 for clear all the texture units + void (*GL_TexGen)( unsigned int coord, unsigned int mode ); + void (*GL_TextureTarget)( unsigned int target ); // change texture unit mode without bind texture + void (*GL_TexCoordArrayMode)( unsigned int texmode ); + void (*GL_UpdateTexSize)( int texnum, int width, int height, int depth ); // recalc statistics + void (*GL_Reserved0)( void ); // for potential interface expansion without broken compatibility + void (*GL_Reserved1)( void ); + + // Misc renderer functions + void (*GL_DrawParticles)( const struct ref_viewpass_s *rvp, qboolean trans_pass, float frametime ); + colorVec (*LightVec)( const float *start, const float *end, float *lightspot, float *lightvec ); + struct mstudiotex_s *( *StudioGetTexture )( struct cl_entity_s *e ); + + // passed through R_RenderFrame (0 - use engine renderer, 1 - use custom client renderer) + int (*GL_RenderFrame)( const struct ref_viewpass_s *rvp ); + // build all the lightmaps on new level or when gamma is changed + void (*GL_BuildLightmaps)( void ); + // setup map bounds for ortho-projection when we in dev_overview mode + void (*GL_OrthoBounds)( const float *mins, const float *maxs ); + // grab r_speeds message + qboolean (*R_SpeedsMessage)( char *out, size_t size ); + // get visdata for current frame from custom renderer + byte* (*Mod_GetCurrentVis)( void ); + // tell the renderer what new map is started + void (*R_NewMap)( void ); + // clear the render entities before each frame + void (*R_ClearScene)( void ); + + // TriAPI Interface + // NOTE: implementation isn't required to be compatible + void (*TriRenderMode)( int mode ); + void (*Begin)( int primitiveCode ); + void (*End)( void ); + void (*Color4f)( float r, float g, float b, float a ); + void (*Color4ub)( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); + void (*TexCoord2f)( float u, float v ); + void (*Vertex3fv)( const float *worldPnt ); + void (*Vertex3f)( float x, float y, float z ); + int (*WorldToScreen)( const float *world, float *screen ); // Returns 1 if it's z clipped + void (*Fog)( float flFogColor[3], float flStart, float flEnd, int bOn ); //Works just like GL_FOG, flFogColor is r/g/b. + void (*ScreenToWorld)( const float *screen, float *world ); + void (*GetMatrix)( const int pname, float *matrix ); + void (*FogParams)( float flDensity, int iFogSkybox ); + void (*CullFace)( TRICULLSTYLE mode ); + + // vgui drawing implementation + void (*VGUI_DrawInit)( void ); + void (*VGUI_DrawShutdown)( void ); + void (*VGUI_SetupDrawingText)( int *pColor ); + void (*VGUI_SetupDrawingRect)( int *pColor ); + void (*VGUI_SetupDrawingImage)( int *pColor ); + void (*VGUI_BindTexture)( int id ); + void (*VGUI_EnableTexture)( qboolean enable ); + void (*VGUI_CreateTexture)( int id, int width, int height ); + void (*VGUI_UploadTexture)( int id, const char *buffer, int width, int height ); + void (*VGUI_UploadTextureBlock)( int id, int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight ); + void (*VGUI_DrawQuad)( const vpoint_t *ul, const vpoint_t *lr ); + void (*VGUI_GetTextureSizes)( int *width, int *height ); + int (*VGUI_GenerateTexture)( void ); + +} ref_interface_t; + +typedef int (*REFAPI)( int version, ref_interface_t *pFunctionTable, ref_api_t* engfuncs, ref_globals_t *pGlobals ); + +#endif // REF_API diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 3c9cac80..ff863aba 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -22,6 +22,7 @@ GNU General Public License for more details. #include "studio.h" #include "const.h" #include "render_api.h" // modelstate_t +#include "ref_common.h" // decals #define ENTVARS_COUNT ARRAYSIZE( gEntvarsDescription ) @@ -552,7 +553,7 @@ void SV_RestartStaticEnts( void ) int i; // remove all the static entities on the client - R_ClearStaticEntities(); + CL_ClearStaticEntities(); // resend them again for( i = 0; i < sv.num_static_entities; i++ ) @@ -616,10 +617,21 @@ void SV_RestartDecals( void ) // g-cont. add space for studiodecals if present host.decalList = (decallist_t *)Z_Calloc( sizeof( decallist_t ) * MAX_RENDER_DECALS * 2 ); - host.numdecals = R_CreateDecalList( host.decalList ); - // remove decals from map - R_ClearAllDecals(); +#ifndef XASH_DEDICATED + if( ref.dllFuncs.R_CreateDecalList ) + { + host.numdecals = ref.dllFuncs.R_CreateDecalList( host.decalList ); + + // remove decals from map + ref.dllFuncs.R_ClearAllDecals(); + } + else +#endif // XASH_DEDICATED + { + // we probably running a dedicated server + host.numdecals = 0; + } // write decals into reliable datagram msg = SV_GetReliableDatagram(); @@ -4964,7 +4976,9 @@ void SV_UnloadProgs( void ) SV_DeactivateServer (); Delta_Shutdown (); - Mod_ClearUserData (); + /// TODO: reenable this when + /// SV_UnloadProgs will be disabled + //Mod_ClearUserData (); SV_FreeStringPool(); diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index efd74a2c..073d8f6c 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -18,7 +18,7 @@ GNU General Public License for more details. #include "const.h" #include "library.h" #include "triangleapi.h" -#include "gl_export.h" +#include "ref_common.h" typedef int (*PHYSICAPI)( int, server_physics_api_t*, physics_interface_t* ); #ifndef XASH_DEDICATED @@ -1884,17 +1884,19 @@ void SV_DrawDebugTriangles( void ) if( svgame.physFuncs.DrawDebugTriangles != NULL ) { +#if 0 // debug draws only pglDisable( GL_BLEND ); pglDepthMask( GL_FALSE ); pglDisable( GL_TEXTURE_2D ); - +#endif // draw wireframe overlay svgame.physFuncs.DrawDebugTriangles (); - +#if 0 pglEnable( GL_TEXTURE_2D ); pglDepthMask( GL_TRUE ); pglEnable( GL_BLEND ); +#endif } } @@ -2001,6 +2003,15 @@ const char* pfnGetModelName( int modelindex ) return sv.model_precache[modelindex]; } +static const byte *GL_TextureData( unsigned int texnum ) +{ +#ifndef XASH_DEDICATED + return ref.dllFuncs.GL_TextureData ? ref.dllFuncs.GL_TextureData( texnum ) : NULL; +#else // XASH_DEDICATED + return NULL; +#endif // XASH_DEDICATED +} + static server_physics_api_t gPhysicsAPI = { SV_LinkEdict, diff --git a/engine/server/sv_save.c b/engine/server/sv_save.c index 25dc0d3c..1f937221 100644 --- a/engine/server/sv_save.c +++ b/engine/server/sv_save.c @@ -19,6 +19,7 @@ GNU General Public License for more details. #include "const.h" #include "render_api.h" // decallist_t #include "sound.h" // S_GetDynamicSounds +#include "ref_common.h" // decals /* ============================================================================== @@ -1129,7 +1130,17 @@ static void SaveClientState( SAVERESTOREDATA *pSaveData, const char *level, int decalList = (decallist_t *)Z_Calloc( sizeof( decallist_t ) * MAX_RENDER_DECALS * 2 ); // initialize client header - header.decalCount = R_CreateDecalList( decalList ); +#ifndef XASH_DEDICATED + if( ref.dllFuncs.R_CreateDecalList ) + { + header.decalCount = ref.dllFuncs.R_CreateDecalList( decalList ); + } + else +#endif // XASH_DEDICATED + { + // we probably running a dedicated server + header.decalCount = 0; + } header.entityCount = sv.num_static_entities; if( !changelevel ) diff --git a/engine/wscript b/engine/wscript index 58578030..f691dd64 100644 --- a/engine/wscript +++ b/engine/wscript @@ -52,7 +52,7 @@ def build(bld): bld.load_envs() bld.env = bld.all_envs[get_subproject_name(bld)] - libs = [] + libs = [ 'public' ] source = bld.path.ant_glob([ 'common/*.c', 'common/imagelib/*.c', @@ -89,7 +89,8 @@ def build(bld): if bld.env.DEST_OS == 'linux': libs.append('RT') - includes = ['common', 'server', 'client', 'client/vgui', '.', '../common', '../pm_shared' ] + # HACK: public headers must be put before common, so we don't get wrong mathlib included + includes = ['common', 'server', 'client', 'client/vgui', '.', '../public', '../common', '../pm_shared' ] if bld.env.SINGLE_BINARY: bld( diff --git a/mainui b/mainui index 9acf8b75..f2a54fcb 160000 --- a/mainui +++ b/mainui @@ -1 +1 @@ -Subproject commit 9acf8b75d9d167ac63efd6db8f35c42a2d325082 +Subproject commit f2a54fcb5465d4e3902004228918586aa54e5f47 diff --git a/engine/common/crtlib.c b/public/crtlib.c similarity index 79% rename from engine/common/crtlib.c rename to public/crtlib.c index a4140bcf..2895ae20 100644 --- a/engine/common/crtlib.c +++ b/public/crtlib.c @@ -12,12 +12,15 @@ 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 "port.h" +#include "xash3d_types.h" +#include "const.h" #include #include #include -#include "common.h" - +#include +#include "stdio.h" +#include "crtlib.h" void Q_strnupr( const char *in, char *out, size_t size_out ) { if( size_out == 0 ) return; @@ -178,19 +181,6 @@ size_t Q_strncpy( char *dst, const char *src, size_t size ) return ( s - src - 1 ); // count does not include NULL } -char *_copystring( byte *mempool, const char *s, const char *filename, int fileline ) -{ - char *b; - - if( !s ) return NULL; - if( !mempool ) mempool = host.mempool; - - b = _Mem_Alloc( mempool, Q_strlen( s ) + 1, false, filename, fileline ); - Q_strcpy( b, s ); - - return b; -} - int Q_atoi( const char *str ) { int val = 0; @@ -727,3 +717,171 @@ char *va( const char *format, ... ) return s; } + +/* +============ +COM_FileBase + +Extracts the base name of a file (no path, no extension, assumes '/' as path separator) +============ +*/ +void COM_FileBase( const char *in, char *out ) +{ + int len, start, end; + + len = Q_strlen( in ); + if( !len ) return; + + // scan backward for '.' + end = len - 1; + + while( end && in[end] != '.' && in[end] != '/' && in[end] != '\\' ) + end--; + + if( in[end] != '.' ) + end = len-1; // no '.', copy to end + else end--; // found ',', copy to left of '.' + + // scan backward for '/' + start = len - 1; + + while( start >= 0 && in[start] != '/' && in[start] != '\\' ) + start--; + + if( start < 0 || ( in[start] != '/' && in[start] != '\\' )) + start = 0; + else start++; + + // length of new sting + len = end - start + 1; + + // Copy partial string + Q_strncpy( out, &in[start], len + 1 ); + out[len] = 0; +} + +/* +============ +COM_FileExtension +============ +*/ +const char *COM_FileExtension( const char *in ) +{ + const char *separator, *backslash, *colon, *dot; + + separator = Q_strrchr( in, '/' ); + backslash = Q_strrchr( in, '\\' ); + + if( !separator || separator < backslash ) + separator = backslash; + + colon = Q_strrchr( in, ':' ); + + if( !separator || separator < colon ) + separator = colon; + + dot = Q_strrchr( in, '.' ); + + if( dot == NULL || ( separator && ( dot < separator ))) + return ""; + + return dot + 1; +} + +/* +============ +COM_FileWithoutPath +============ +*/ +const char *COM_FileWithoutPath( const char *in ) +{ + const char *separator, *backslash, *colon; + + separator = Q_strrchr( in, '/' ); + backslash = Q_strrchr( in, '\\' ); + + if( !separator || separator < backslash ) + separator = backslash; + + colon = Q_strrchr( in, ':' ); + + if( !separator || separator < colon ) + separator = colon; + + return separator ? separator + 1 : in; +} + +/* +============ +COM_ExtractFilePath +============ +*/ +void COM_ExtractFilePath( const char *path, char *dest ) +{ + const char *src = path + Q_strlen( path ) - 1; + + // back up until a \ or the start + while( src != path && !(*(src - 1) == '\\' || *(src - 1) == '/' )) + src--; + + if( src != path ) + { + memcpy( dest, path, src - path ); + dest[src - path - 1] = 0; // cutoff backslash + } + else Q_strcpy( dest, "" ); // file without path +} + +/* +============ +COM_StripExtension +============ +*/ +void COM_StripExtension( char *path ) +{ + size_t length; + + length = Q_strlen( path ) - 1; + while( length > 0 && path[length] != '.' ) + { + length--; + if( path[length] == '/' || path[length] == '\\' || path[length] == ':' ) + return; // no extension + } + + if( length ) path[length] = 0; +} + +/* +================== +COM_DefaultExtension +================== +*/ +void COM_DefaultExtension( char *path, const char *extension ) +{ + const char *src; + + // if path doesn't have a .EXT, append extension + // (extension should include the .) + src = path + Q_strlen( path ) - 1; + + while( *src != '/' && src != path ) + { + // it has an extension + if( *src == '.' ) return; + src--; + } + + Q_strcat( path, extension ); +} + +/* +================== +COM_ReplaceExtension +================== +*/ +void COM_ReplaceExtension( char *path, const char *extension ) +{ + COM_StripExtension( path ); + COM_DefaultExtension( path, extension ); +} diff --git a/public/crtlib.h b/public/crtlib.h new file mode 100644 index 00000000..439065f7 --- /dev/null +++ b/public/crtlib.h @@ -0,0 +1,82 @@ +/* +crtlib.h - internal stdlib +Copyright (C) 2011 Uncle Mike + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + +#ifndef STDLIB_H +#define STDLIB_H + +#ifdef __GNUC__ +#define _format(x) __attribute__((format(printf, x, x+1))) +#else +#define _format(x) +#endif + +// timestamp modes +enum +{ + TIME_FULL = 0, + TIME_DATE_ONLY, + TIME_TIME_ONLY, + TIME_NO_SECONDS, + TIME_YEAR_ONLY, + TIME_FILENAME, +}; + +// +// crtlib.c +// +#define Q_strupr( in, out ) Q_strnupr( in, out, 99999 ) +void Q_strnupr( const char *in, char *out, size_t size_out ); +#define Q_strlwr( in, out ) Q_strnlwr( in, out, 99999 ) +void Q_strnlwr( const char *in, char *out, size_t size_out ); +int Q_strlen( const char *string ); +int Q_colorstr( const char *string ); +char Q_toupper( const char in ); +char Q_tolower( const char in ); +#define Q_strcat( dst, src ) Q_strncat( dst, src, 99999 ) +size_t Q_strncat( char *dst, const char *src, size_t siz ); +#define Q_strcpy( dst, src ) Q_strncpy( dst, src, 99999 ) +size_t Q_strncpy( char *dst, const char *src, size_t siz ); +uint Q_hashkey( const char *string, uint hashSize, qboolean caseinsensitive ); +qboolean Q_isdigit( const char *str ); +int Q_atoi( const char *str ); +float Q_atof( const char *str ); +void Q_atov( float *vec, const char *str, size_t siz ); +char *Q_strchr( const char *s, char c ); +char *Q_strrchr( const char *s, char c ); +#define Q_stricmp( s1, s2 ) Q_strnicmp( s1, s2, 99999 ) +int Q_strnicmp( const char *s1, const char *s2, int n ); +#define Q_strcmp( s1, s2 ) Q_strncmp( s1, s2, 99999 ) +int Q_strncmp( const char *s1, const char *s2, int n ); +qboolean Q_stricmpext( const char *s1, const char *s2 ); +const char *Q_timestamp( int format ); +char *Q_stristr( const char *string, const char *string2 ); +char *Q_strstr( const char *string, const char *string2 ); +#define Q_vsprintf( buffer, format, args ) Q_vsnprintf( buffer, 99999, format, args ) +int Q_vsnprintf( char *buffer, size_t buffersize, const char *format, va_list args ); +int Q_snprintf( char *buffer, size_t buffersize, const char *format, ... ) _format( 3 ); +int Q_sprintf( char *buffer, const char *format, ... ) _format( 2 ); +#define Q_memprint( val ) Q_pretifymem( val, 2 ) +char *Q_pretifymem( float value, int digitsafterdecimal ); +char *va( const char *format, ... ) _format( 1 ); +void COM_FileBase( const char *in, char *out ); +const char *COM_FileExtension( const char *in ); +void COM_DefaultExtension( char *path, const char *extension ); +void COM_ReplaceExtension( char *path, const char *extension ); +void COM_ExtractFilePath( const char *path, char *dest ); +const char *COM_FileWithoutPath( const char *in ); +void COM_StripExtension( char *path ); +#define COM_CheckString( string ) ( ( !string || !*string ) ? 0 : 1 ) + +#endif//STDLIB_H diff --git a/engine/common/mathlib.c b/public/mathlib.c similarity index 83% rename from engine/common/mathlib.c rename to public/mathlib.c index 62f98ad0..4351cf83 100644 --- a/engine/common/mathlib.c +++ b/public/mathlib.c @@ -12,9 +12,11 @@ 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 "port.h" +#include "xash3d_types.h" +#include "const.h" +#include "com_model.h" #include -#include "common.h" #include "mathlib.h" #include "eiface.h" @@ -762,3 +764,111 @@ void QuaternionSlerp( const vec4_t p, const vec4_t q, float t, vec4_t qt ) QuaternionSlerpNoAlign( p, q2, t, qt ); } + +/* +==================== +V_CalcFov +==================== +*/ +float V_CalcFov( float *fov_x, float width, float height ) +{ + float x, half_fov_y; + + if( *fov_x < 1.0f || *fov_x > 179.0f ) + *fov_x = 90.0f; // default value + + x = width / tan( DEG2RAD( *fov_x ) * 0.5f ); + half_fov_y = atan( height / x ); + + return RAD2DEG( half_fov_y ) * 2; +} + +/* +==================== +V_AdjustFov +==================== +*/ +void V_AdjustFov( float *fov_x, float *fov_y, float width, float height, qboolean lock_x ) +{ + float x, y; + + if( width * 3 == 4 * height || width * 4 == height * 5 ) + { + // 4:3 or 5:4 ratio + return; + } + + if( lock_x ) + { + *fov_y = 2 * atan((width * 3) / (height * 4) * tan( *fov_y * M_PI / 360.0 * 0.5 )) * 360 / M_PI; + return; + } + + y = V_CalcFov( fov_x, 640, 480 ); + x = *fov_x; + + *fov_x = V_CalcFov( &y, height, width ); + if( *fov_x < x ) *fov_x = x; + else *fov_y = y; +} + +/* +================== +BoxOnPlaneSide + +Returns 1, 2, or 1 + 2 +================== +*/ +int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const mplane_t *p ) +{ + float dist1, dist2; + int sides = 0; + + // general case + switch( p->signbits ) + { + case 0: + dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; + dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; + break; + case 1: + dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; + dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; + break; + case 2: + dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; + dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; + break; + case 3: + dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; + dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; + break; + case 4: + dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; + dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; + break; + case 5: + dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; + dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; + break; + case 6: + dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; + dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; + break; + case 7: + dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; + dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; + break; + default: + // shut up compiler + dist1 = dist2 = 0; + break; + } + + if( dist1 >= p->dist ) + sides = 1; + if( dist2 < p->dist ) + sides |= 2; + + return sides; +} diff --git a/engine/common/mathlib.h b/public/mathlib.h similarity index 95% rename from engine/common/mathlib.h rename to public/mathlib.h index f939dc10..b69deceb 100644 --- a/engine/common/mathlib.h +++ b/public/mathlib.h @@ -193,6 +193,26 @@ void Matrix4x4_OriginFromMatrix( const matrix4x4 in, float *out ); void Matrix4x4_Transpose( matrix4x4 out, const matrix4x4 in1 ); qboolean Matrix4x4_Invert_Full( matrix4x4 out, const matrix4x4 in1 ); +float V_CalcFov( float *fov_x, float width, float height ); +void V_AdjustFov( float *fov_x, float *fov_y, float width, float height, qboolean lock_x ); + +int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const mplane_t *p ); +#define BOX_ON_PLANE_SIDE( emins, emaxs, p ) \ + ((( p )->type < 3 ) ? \ + ( \ + ((p)->dist <= (emins)[(p)->type]) ? \ + 1 \ + : \ + ( \ + ((p)->dist >= (emaxs)[(p)->type]) ? \ + 2 \ + : \ + 3 \ + ) \ + ) \ + : \ + BoxOnPlaneSide(( emins ), ( emaxs ), ( p ))) + extern vec3_t vec3_origin; extern int boxpnt[6][4]; extern const matrix3x4 matrix3x4_identity; diff --git a/engine/common/matrixlib.c b/public/matrixlib.c similarity index 99% rename from engine/common/matrixlib.c rename to public/matrixlib.c index d656d53a..18ded0e1 100644 --- a/engine/common/matrixlib.c +++ b/public/matrixlib.c @@ -13,7 +13,10 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include "common.h" +#include "port.h" +#include "xash3d_types.h" +#include "const.h" +#include "com_model.h" #include "mathlib.h" const matrix3x4 matrix3x4_identity = @@ -845,4 +848,4 @@ qboolean Matrix4x4_Invert_Full( matrix4x4 out, const matrix4x4 in1 ) } } return false; -} \ No newline at end of file +} diff --git a/public/wscript b/public/wscript new file mode 100644 index 00000000..1906df6f --- /dev/null +++ b/public/wscript @@ -0,0 +1,36 @@ +#! /usr/bin/env python +# encoding: utf-8 +# mittorn, 2018 + +from waflib import Logs +import os +from fwgslib import get_subproject_name + +top = '.' + +def options(opt): + # stub + return + +def configure(conf): + # stub + return + +def build(bld): + bld.load_envs() + name = get_subproject_name(bld) + bld.env = bld.all_envs[name] + + source = bld.path.ant_glob(['*.c']) + libs = [] + includes = [ '.', '../common', '../engine' ] + + bld.stlib( + source = source, + target = name, + features = 'c', + includes = includes, + use = libs, + install_path = bld.env.LIBDIR, + subsystem = bld.env.MSVC_SUBSYSTEM + ) diff --git a/engine/client/gl_alias.c b/ref_gl/gl_alias.c similarity index 93% rename from engine/client/gl_alias.c rename to ref_gl/gl_alias.c index 6226c90b..736adb4f 100644 --- a/engine/client/gl_alias.c +++ b/ref_gl/gl_alias.c @@ -12,17 +12,14 @@ 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" +#include "pmtrace.h" extern cvar_t r_shadows; @@ -421,6 +418,7 @@ rgbdata_t *Mod_CreateSkinData( model_t *mod, byte *data, int width, int height ) static rgbdata_t skin; char name[MAX_QPATH]; int i; + model_t *loadmodel = gEngfuncs.Mod_GetCurrentLoadingModel(); skin.width = width; skin.height = height; @@ -430,10 +428,10 @@ rgbdata_t *Mod_CreateSkinData( model_t *mod, byte *data, int width, int height ) skin.encode = DXT_ENCODE_DEFAULT; skin.numMips = 1; skin.buffer = data; - skin.palette = (byte *)&clgame.palette; + skin.palette = (byte *)gEngfuncs.CL_GetPaletteColor( 0 ); skin.size = width * height; - if( !Image_CustomPalette() ) + if( !gEngfuncs.Image_CustomPalette() ) { for( i = 0; i < skin.width * skin.height; i++ ) { @@ -475,7 +473,7 @@ rgbdata_t *Mod_CreateSkinData( model_t *mod, byte *data, int width, int height ) } // make an copy - return FS_CopyImage( &skin ); + return gEngfuncs.FS_CopyImage( &skin ); } void *Mod_LoadSingleSkin( daliasskintype_t *pskintype, int skinnum, int size ) @@ -483,18 +481,19 @@ void *Mod_LoadSingleSkin( daliasskintype_t *pskintype, int skinnum, int size ) string name, lumaname; string checkname; rgbdata_t *pic; + model_t *loadmodel = gEngfuncs.Mod_GetCurrentLoadingModel(); Q_snprintf( name, sizeof( name ), "%s:frame%i", loadmodel->name, skinnum ); Q_snprintf( lumaname, sizeof( lumaname ), "%s:luma%i", loadmodel->name, skinnum ); Q_snprintf( checkname, sizeof( checkname ), "%s_%i.tga", loadmodel->name, skinnum ); - if( !FS_FileExists( checkname, false ) || ( pic = FS_LoadImage( checkname, NULL, 0 )) == NULL ) + if( !gEngfuncs.FS_FileExists( checkname, false ) || ( pic = gEngfuncs.FS_LoadImage( checkname, NULL, 0 )) == NULL ) pic = Mod_CreateSkinData( loadmodel, (byte *)(pskintype + 1), m_pAliasHeader->skinwidth, m_pAliasHeader->skinheight ); m_pAliasHeader->gl_texturenum[skinnum][0] = m_pAliasHeader->gl_texturenum[skinnum][1] = m_pAliasHeader->gl_texturenum[skinnum][2] = m_pAliasHeader->gl_texturenum[skinnum][3] = GL_LoadTextureInternal( name, pic, 0 ); - FS_FreeImage( pic ); + gEngfuncs.FS_FreeImage( pic ); if( R_GetTexture( m_pAliasHeader->gl_texturenum[skinnum][0] )->flags & TF_HAS_LUMA ) { @@ -503,7 +502,7 @@ void *Mod_LoadSingleSkin( daliasskintype_t *pskintype, int skinnum, int size ) m_pAliasHeader->fb_texturenum[skinnum][1] = m_pAliasHeader->fb_texturenum[skinnum][2] = m_pAliasHeader->fb_texturenum[skinnum][3] = GL_LoadTextureInternal( lumaname, pic, TF_MAKELUMA ); - FS_FreeImage( pic ); + gEngfuncs.FS_FreeImage( pic ); } return ((byte *)(pskintype + 1) + size); @@ -516,6 +515,7 @@ void *Mod_LoadGroupSkin( daliasskintype_t *pskintype, int skinnum, int size ) string name, lumaname; rgbdata_t *pic; int i, j; + model_t *loadmodel = gEngfuncs.Mod_GetCurrentLoadingModel(); // animating skin group. yuck. pskintype++; @@ -528,14 +528,14 @@ void *Mod_LoadGroupSkin( daliasskintype_t *pskintype, int skinnum, int size ) Q_snprintf( name, sizeof( name ), "%s_%i_%i", loadmodel->name, skinnum, i ); pic = Mod_CreateSkinData( loadmodel, (byte *)(pskintype), m_pAliasHeader->skinwidth, m_pAliasHeader->skinheight ); m_pAliasHeader->gl_texturenum[skinnum][i & 3] = GL_LoadTextureInternal( name, pic, 0 ); - FS_FreeImage( pic ); + gEngfuncs.FS_FreeImage( pic ); if( R_GetTexture( m_pAliasHeader->gl_texturenum[skinnum][i & 3] )->flags & TF_HAS_LUMA ) { Q_snprintf( lumaname, sizeof( lumaname ), "%s_%i_%i_luma", loadmodel->name, skinnum, i ); pic = Mod_CreateSkinData( NULL, (byte *)(pskintype), m_pAliasHeader->skinwidth, m_pAliasHeader->skinheight ); m_pAliasHeader->fb_texturenum[skinnum][i & 3] = GL_LoadTextureInternal( lumaname, pic, TF_MAKELUMA ); - FS_FreeImage( pic ); + gEngfuncs.FS_FreeImage( pic ); } pskintype = (daliasskintype_t *)((byte *)(pskintype) + size); @@ -560,7 +560,7 @@ void *Mod_LoadAllSkins( int numskins, daliasskintype_t *pskintype ) int i, size; if( numskins < 1 || numskins > MAX_SKINS ) - Host_Error( "Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins ); + gEngfuncs.Host_Error( "Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins ); size = m_pAliasHeader->skinwidth * m_pAliasHeader->skinheight; @@ -634,7 +634,7 @@ void Mod_LoadAliasModel( model_t *mod, const void *buffer, qboolean *loaded ) if( i != ALIAS_VERSION ) { - Con_DPrintf( S_ERROR "%s has wrong version number (%i should be %i)\n", mod->name, i, ALIAS_VERSION ); + gEngfuncs.Con_DPrintf( S_ERROR "%s has wrong version number (%i should be %i)\n", mod->name, i, ALIAS_VERSION ); return; } @@ -661,7 +661,7 @@ void Mod_LoadAliasModel( model_t *mod, const void *buffer, qboolean *loaded ) if( m_pAliasHeader->numverts > MAXALIASVERTS ) { - Con_DPrintf( S_ERROR "model %s has too many vertices\n", mod->name ); + gEngfuncs.Con_DPrintf( S_ERROR "model %s has too many vertices\n", mod->name ); return; } @@ -723,27 +723,17 @@ void Mod_LoadAliasModel( model_t *mod, const void *buffer, qboolean *loaded ) GL_MakeAliasModelDisplayLists( mod ); // move the complete, relocatable alias model to the cache - loadmodel->cache.data = m_pAliasHeader; + gEngfuncs.Mod_GetCurrentLoadingModel()->cache.data = m_pAliasHeader; if( loaded ) *loaded = true; // done } -/* -================= -Mod_UnloadAliasModel -================= -*/ -void Mod_UnloadAliasModel( model_t *mod ) +void Mod_AliasUnloadTextures( void *data ) { aliashdr_t *palias; int i, j; - Assert( mod != NULL ); - - if( mod->type != mod_alias ) - return; // not an alias - - palias = mod->cache.data; + palias = data; if( !palias ) return; // already freed for( i = 0; i < MAX_SKINS; i++ ) @@ -757,9 +747,6 @@ void Mod_UnloadAliasModel( model_t *mod ) GL_FreeTexture( palias->fb_texturenum[i][j] ); } } - - Mem_FreePool( &mod->mempool ); - memset( mod, 0, sizeof( *mod )); } /* @@ -779,7 +766,7 @@ similar to R_StudioDynamicLight */ void R_AliasDynamicLight( cl_entity_t *ent, alight_t *plight ) { - movevars_t *mv = &clgame.movevars; + movevars_t *mv = gEngfuncs.pfnGetMoveVars(); vec3_t lightDir, vecSrc, vecEnd; vec3_t origin, dist, finalLight; float add, radius, total; @@ -815,7 +802,7 @@ void R_AliasDynamicLight( cl_entity_t *ent, alight_t *plight ) msurface_t *psurf = NULL; pmtrace_t trace; - if( FBitSet( host.features, ENGINE_WRITE_LARGE_COORD )) + if( FBitSet( ENGINE_GET_PARM( PARM_FEATURES ), ENGINE_WRITE_LARGE_COORD )) { vecEnd[0] = origin[0] - mv->skyvec_x * 65536.0f; vecEnd[1] = origin[1] - mv->skyvec_y * 65536.0f; @@ -828,17 +815,17 @@ void R_AliasDynamicLight( cl_entity_t *ent, alight_t *plight ) vecEnd[2] = origin[2] - mv->skyvec_z * 8192.0f; } - trace = CL_TraceLine( vecSrc, vecEnd, PM_STUDIO_IGNORE ); - if( trace.ent > 0 ) psurf = PM_TraceSurface( &clgame.pmove->physents[trace.ent], vecSrc, vecEnd ); - else psurf = PM_TraceSurface( clgame.pmove->physents, vecSrc, vecEnd ); + trace = gEngfuncs.CL_TraceLine( vecSrc, vecEnd, PM_STUDIO_IGNORE ); + if( trace.ent > 0 ) psurf = gEngfuncs.EV_TraceSurface( trace.ent, vecSrc, vecEnd ); + else psurf = gEngfuncs.EV_TraceSurface( 0, vecSrc, vecEnd ); if( psurf && FBitSet( psurf->flags, SURF_DRAWSKY )) { VectorSet( lightDir, mv->skyvec_x, mv->skyvec_y, mv->skyvec_z ); - light.r = LightToTexGamma( bound( 0, mv->skycolor_r, 255 )); - light.g = LightToTexGamma( bound( 0, mv->skycolor_g, 255 )); - light.b = LightToTexGamma( bound( 0, mv->skycolor_b, 255 )); + light.r = gEngfuncs.LightToTexGamma( bound( 0, mv->skycolor_r, 255 )); + light.g = gEngfuncs.LightToTexGamma( bound( 0, mv->skycolor_g, 255 )); + light.b = gEngfuncs.LightToTexGamma( bound( 0, mv->skycolor_b, 255 )); } } @@ -899,8 +886,10 @@ void R_AliasDynamicLight( cl_entity_t *ent, alight_t *plight ) // scale lightdir by light intentsity VectorScale( lightDir, total, lightDir ); - for( lnum = 0, dl = cl_dlights; lnum < MAX_DLIGHTS; lnum++, dl++ ) + for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ ) { + dl = gEngfuncs.GetDynamicLight( lnum ); + if( dl->die < g_alias.time || !r_dynamic->value ) continue; @@ -919,9 +908,9 @@ void R_AliasDynamicLight( cl_entity_t *ent, alight_t *plight ) VectorAdd( lightDir, dist, lightDir ); - finalLight[0] += LightToTexGamma( dl->color.r ) * ( add / 256.0f ) * 2.0f; - finalLight[1] += LightToTexGamma( dl->color.g ) * ( add / 256.0f ) * 2.0f; - finalLight[2] += LightToTexGamma( dl->color.b ) * ( add / 256.0f ) * 2.0f; + finalLight[0] += gEngfuncs.LightToTexGamma( dl->color.r ) * ( add / 256.0f ) * 2.0f; + finalLight[1] += gEngfuncs.LightToTexGamma( dl->color.g ) * ( add / 256.0f ) * 2.0f; + finalLight[2] += gEngfuncs.LightToTexGamma( dl->color.b ) * ( add / 256.0f ) * 2.0f; } } @@ -1016,11 +1005,11 @@ R_AliasSetRemapColors */ void R_AliasSetRemapColors( int newTop, int newBottom ) { - CL_AllocRemapInfo( newTop, newBottom ); + gEngfuncs.CL_AllocRemapInfo( newTop, newBottom ); - if( CL_GetRemapInfoForEntity( RI.currententity )) + if( gEngfuncs.CL_GetRemapInfoForEntity( RI.currententity )) { - CL_UpdateRemapInfo( newTop, newBottom ); + gEngfuncs.CL_UpdateRemapInfo( newTop, newBottom ); m_fDoRemap = true; } } @@ -1180,7 +1169,7 @@ void R_AliasLerpMovement( cl_entity_t *e ) if( g_alias.interpolate && ( g_alias.time < e->curstate.animtime + 1.0f ) && ( e->curstate.animtime != e->latched.prevanimtime )) f = ( g_alias.time - e->curstate.animtime ) / ( e->curstate.animtime - e->latched.prevanimtime ); - if( cls.demoplayback == DEMO_QUAKE1 ) + if( ENGINE_GET_PARM( PARM_PLAYING_DEMO ) == DEMO_QUAKE1 ) f = f + 1.0f; g_alias.lerpfrac = bound( 0.0f, f, 1.0f ); @@ -1230,7 +1219,7 @@ void R_SetupAliasFrame( cl_entity_t *e, aliashdr_t *paliashdr ) else if( newframe >= paliashdr->numframes ) { if( newframe > paliashdr->numframes ) - Con_Reportf( S_WARN "R_GetAliasFrame: no such frame %d (%s)\n", newframe, e->model->name ); + gEngfuncs.Con_Reportf( S_WARN "R_GetAliasFrame: no such frame %d (%s)\n", newframe, e->model->name ); newframe = paliashdr->numframes - 1; } @@ -1273,7 +1262,7 @@ static void R_AliasDrawAbsBBox( cl_entity_t *e, const vec3_t absmin, const vec3_ int i; // looks ugly, skip - if( r_drawentities->value != 5 || e == &clgame.viewent ) + if( r_drawentities->value != 5 || e == gEngfuncs.GetViewModel() ) return; // compute a full bounding box @@ -1349,12 +1338,12 @@ static void R_AliasSetupTimings( void ) if( RI.drawWorld ) { // synchronize with server time - g_alias.time = cl.time; + g_alias.time = gpGlobals->time; } else { // menu stuff - g_alias.time = host.realtime; + g_alias.time = gpGlobals->realtime; } m_fDoRemap = false; @@ -1387,7 +1376,7 @@ void R_DrawAliasModel( cl_entity_t *e ) // // locate the proper data // - m_pAliasHeader = (aliashdr_t *)Mod_AliasExtradata( RI.currententity->model ); + m_pAliasHeader = (aliashdr_t *)gEngfuncs.Mod_Extradata( mod_alias, RI.currententity->model ); if( !m_pAliasHeader ) return; // init time @@ -1398,7 +1387,7 @@ void R_DrawAliasModel( cl_entity_t *e ) R_AliasLerpMovement( e ); - if( !FBitSet( host.features, ENGINE_COMPENSATE_QUAKE_BUG )) + if( !FBitSet( ENGINE_GET_PARM( PARM_FEATURES ), ENGINE_COMPENSATE_QUAKE_BUG )) e->angles[PITCH] = -e->angles[PITCH]; // stupid quake bug // don't rotate clients, only aim @@ -1445,7 +1434,7 @@ void R_DrawAliasModel( cl_entity_t *e ) anim = (int)(g_alias.time * 10) & 3; skin = bound( 0, RI.currententity->curstate.skin, m_pAliasHeader->numskins - 1 ); - if( m_fDoRemap ) pinfo = CL_GetRemapInfoForEntity( e ); + if( m_fDoRemap ) pinfo = gEngfuncs.CL_GetRemapInfoForEntity( e ); if( r_lightmap->value && !r_fullbright->value ) GL_Bind( XASH_TEXTURE0, tr.whiteTexture ); diff --git a/engine/client/gl_backend.c b/ref_gl/gl_backend.c similarity index 85% rename from engine/client/gl_backend.c rename to ref_gl/gl_backend.c index 84c7a352..c18c9d26 100644 --- a/engine/client/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" @@ -28,9 +27,9 @@ R_SpeedsMessage */ qboolean R_SpeedsMessage( char *out, size_t size ) { - if( clgame.drawFuncs.R_SpeedsMessage != NULL ) + if( gEngfuncs.drawFuncs->R_SpeedsMessage != NULL ) { - if( clgame.drawFuncs.R_SpeedsMessage( out, size )) + if( gEngfuncs.drawFuncs->R_SpeedsMessage( out, size )) return true; // otherwise pass to default handler } @@ -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: @@ -106,7 +105,7 @@ void GL_BackendEndFrame( void ) break; case 4: Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i static entities\n%3i normal entities\n%3i server entities", - r_numStatics, r_numEntities - r_numStatics, pfnNumberOfEntities( )); + r_numStatics, r_numEntities - r_numStatics, ENGINE_GET_PARM( PARM_NUMENTITIES )); break; case 5: Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i tempents\n%3i viewbeams\n%3i particles", @@ -185,7 +184,7 @@ void GL_SelectTexture( GLint tmu ) if( tmu >= GL_MaxTextureUnits( )) { - Con_Reportf( S_ERROR "GL_SelectTexture: bad tmu state %i\n", tmu ); + gEngfuncs.Con_Reportf( S_ERROR "GL_SelectTexture: bad tmu state %i\n", tmu ); return; } @@ -278,7 +277,7 @@ void GL_TextureTarget( uint target ) { if( glState.activeTMU < 0 || glState.activeTMU >= GL_MaxTextureUnits( )) { - Con_Reportf( S_ERROR "GL_TextureTarget: bad tmu state %i\n", glState.activeTMU ); + gEngfuncs.Con_Reportf( S_ERROR "GL_TextureTarget: bad tmu state %i\n", glState.activeTMU ); return; } @@ -453,37 +452,6 @@ const envmap_t r_envMapInfo[6] = {{ 90, 0, 90}, 0 } }; -/* -=============== -VID_WriteOverviewScript - -Create overview script file -=============== -*/ -void VID_WriteOverviewScript( void ) -{ - ref_overview_t *ov = &clgame.overView; - string filename; - file_t *f; - - Q_snprintf( filename, sizeof( filename ), "overviews/%s.txt", clgame.mapname ); - - f = FS_Open( filename, "w", false ); - if( !f ) return; - - FS_Printf( f, "// overview description file for %s.bsp\n\n", clgame.mapname ); - FS_Print( f, "global\n{\n" ); - FS_Printf( f, "\tZOOM\t%.2f\n", ov->flZoom ); - FS_Printf( f, "\tORIGIN\t%.2f\t%.2f\t%.2f\n", ov->origin[0], ov->origin[1], ov->origin[2] ); - FS_Printf( f, "\tROTATED\t%i\n", ov->rotated ? 1 : 0 ); - FS_Print( f, "}\n\nlayer\n{\n" ); - FS_Printf( f, "\tIMAGE\t\"overviews/%s.bmp\"\n", clgame.mapname ); - FS_Printf( f, "\tHEIGHT\t%.2f\n", ov->zFar ); // ??? - FS_Print( f, "}\n" ); - - FS_Close( f ); -} - qboolean VID_ScreenShot( const char *filename, int shot_type ) { rgbdata_t *r_shot; @@ -492,11 +460,11 @@ qboolean VID_ScreenShot( const char *filename, int shot_type ) qboolean result; r_shot = Mem_Calloc( r_temppool, sizeof( rgbdata_t )); - r_shot->width = (glState.width + 3) & ~3; - r_shot->height = (glState.height + 3) & ~3; + r_shot->width = (gpGlobals->width + 3) & ~3; + r_shot->height = (gpGlobals->height + 3) & ~3; r_shot->flags = IMAGE_HAS_COLOR; r_shot->type = PF_RGB_24; - r_shot->size = r_shot->width * r_shot->height * PFDesc[r_shot->type].bpp; + r_shot->size = r_shot->width * r_shot->height * gEngfuncs.Image_GetPFDesc( r_shot->type )->bpp; r_shot->palette = NULL; r_shot->buffer = Mem_Malloc( r_temppool, r_shot->size ); @@ -508,11 +476,11 @@ qboolean VID_ScreenShot( const char *filename, int shot_type ) case VID_SCREENSHOT: break; case VID_SNAPSHOT: - FS_AllowDirectPaths( true ); + gEngfuncs.FS_AllowDirectPaths( true ); break; case VID_LEVELSHOT: flags |= IMAGE_RESAMPLE; - if( glState.wideScreen ) + if( gpGlobals->wideScreen ) { height = 480; width = 800; @@ -529,20 +497,19 @@ qboolean VID_ScreenShot( const char *filename, int shot_type ) width = 320; break; case VID_MAPSHOT: - VID_WriteOverviewScript(); // store overview script too flags |= IMAGE_RESAMPLE|IMAGE_QUANTIZE; // GoldSrc request overviews in 8-bit format height = 768; width = 1024; break; } - Image_Process( &r_shot, width, height, flags, 0.0f ); + gEngfuncs.Image_Process( &r_shot, width, height, flags, 0.0f ); // write image - result = FS_SaveImage( filename, r_shot ); - host.write_to_clipboard = false; // disable write to clipboard - FS_AllowDirectPaths( false ); // always reset after store screenshot - FS_FreeImage( r_shot ); + result = gEngfuncs.FS_SaveImage( filename, r_shot ); + // REFTODO: host.write_to_clipboard = false; // disable write to clipboard + gEngfuncs.FS_AllowDirectPaths( false ); // always reset after store screenshot + gEngfuncs.FS_FreeImage( r_shot ); return result; } @@ -560,14 +527,14 @@ 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 while( i < size ) i<<=1; if( i != size ) return false; - if( size > glState.width || size > glState.height ) + if( size > gpGlobals->width || size > gpGlobals->height ) return false; // setup refdef @@ -605,7 +572,7 @@ qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qbo r_side->size = r_side->width * r_side->height * 3; r_side->buffer = temp; - if( flags ) Image_Process( &r_side, 0, 0, flags, 0.0f ); + if( flags ) gEngfuncs.Image_Process( &r_side, 0, 0, flags, 0.0f ); memcpy( buffer + (size * size * 3 * i), r_side->buffer, size * size * 3 ); } @@ -626,9 +593,9 @@ qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qbo COM_DefaultExtension( basename, ".tga" ); // write image as 6 sides - result = FS_SaveImage( basename, r_shot ); - FS_FreeImage( r_shot ); - FS_FreeImage( r_side ); + result = gEngfuncs.FS_SaveImage( basename, r_shot ); + gEngfuncs.FS_FreeImage( r_shot ); + gEngfuncs.FS_FreeImage( r_side ); return result; } @@ -659,7 +626,7 @@ void R_ShowTextures( void ) if( showHelp ) { - CL_CenterPrint( "use '<-' and '->' keys to change atlas page, ESC to quit", 0.25f ); + gEngfuncs.CL_CenterPrint( "use '<-' and '->' keys to change atlas page, ESC to quit", 0.25f ); showHelp = false; } @@ -676,10 +643,10 @@ rebuild_page: end = total * gl_showtextures->value; if( end > MAX_TEXTURES ) end = MAX_TEXTURES; - w = glState.width / base_w; - h = glState.height / base_h; + w = gpGlobals->width / base_w; + h = gpGlobals->height / base_h; - Con_DrawStringLen( NULL, NULL, &charHeight ); + gEngfuncs.Con_DrawStringLen( NULL, NULL, &charHeight ); for( i = j = 0; i < MAX_TEXTURES; i++ ) { @@ -691,7 +658,7 @@ rebuild_page: if( i == MAX_TEXTURES && gl_showtextures->value != 1 ) { // bad case, rewind to one and try again - Cvar_SetValue( "r_showtextures", max( 1, gl_showtextures->value - 1 )); + gEngfuncs.Cvar_SetValue( "r_showtextures", max( 1, gl_showtextures->value - 1 )); if( ++numTries < 2 ) goto rebuild_page; // to prevent infinite loop } @@ -740,11 +707,11 @@ rebuild_page: shortname[17] = '.'; shortname[18] = '\0'; } - Con_DrawString( x + 1, y + h - charHeight, shortname, color ); + gEngfuncs.Con_DrawString( x + 1, y + h - charHeight, shortname, color ); j++, k++; } - CL_DrawCenterPrint (); + gEngfuncs.CL_DrawCenterPrint (); pglFinish(); } @@ -786,7 +753,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 ); @@ -816,10 +783,10 @@ void R_ShowTree_r( mnode_t *node, float x, float y, float scale, int shownodes ) void R_ShowTree( void ) { - float x = (float)((glState.width - (int)POINT_SIZE) >> 1); + float x = (float)((gpGlobals->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 +798,57 @@ 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 ); + gEngfuncs.Con_NPrintf( 0, "max recursion %d\n", tr.max_recursion ); +} + +/* +================ +SCR_TimeRefresh_f + +timerefresh [noflip] +================ +*/ +void SCR_TimeRefresh_f( void ) +{ + int i; + double start, stop; + double time; + + if( ENGINE_GET_PARM( PARM_CONNSTATE ) != ca_active ) + return; + + start = gEngfuncs.pfnTime(); + + // run without page flipping like GoldSrc + if( gEngfuncs.Cmd_Argc() == 1 ) + { + pglDrawBuffer( GL_FRONT ); + for( i = 0; i < 128; i++ ) + { + gpGlobals->viewangles[1] = i / 128.0 * 360.0f; + R_RenderScene(); + } + pglFinish(); + R_EndFrame(); + } + else + { + for( i = 0; i < 128; i++ ) + { + R_BeginFrame( true ); + gpGlobals->viewangles[1] = i / 128.0 * 360.0f; + R_RenderScene(); + R_EndFrame(); + } + } + + stop = gEngfuncs.pfnTime (); + time = (stop - start); + gEngfuncs.Con_Printf( "%f seconds (%f fps)\n", time, 128 / time ); } diff --git a/engine/client/gl_beams.c b/ref_gl/gl_beams.c similarity index 60% rename from engine/client/gl_beams.c rename to ref_gl/gl_beams.c index a8cd6614..9e65219d 100644 --- a/engine/client/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 @@ -53,7 +52,7 @@ static void FracNoise( float *noise, int divs ) if( divs < 2 ) return; // noise is normalized to +/- scale - noise[div2] = ( noise[0] + noise[divs] ) * 0.5f + divs * COM_RandomFloat( -0.125f, 0.125f ); + noise[div2] = ( noise[0] + noise[divs] ) * 0.5f + divs * gEngfuncs.COM_RandomFloat( -0.125f, 0.125f ); if( div2 > 1 ) { @@ -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,19 +133,19 @@ 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; } // check bbox - if( Mod_BoxVisible( mins, maxs, Mod_GetCurrentVis( ))) + if( gEngfuncs.Mod_BoxVisible( mins, maxs, Mod_GetCurrentVis( ))) { 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 ) + { + gEngfuncs.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++; + } +} + + /* ============================================================== @@ -784,7 +583,7 @@ void R_DrawBeamFollow( BEAM *pbeam, float frametime ) vec3_t last1, last2, tmp, screen; vec3_t delta, screenLast, normal; - R_FreeDeadParticles( &pbeam->particles ); + gEngfuncs.R_FreeDeadParticles( &pbeam->particles ); particles = pbeam->particles; pnew = NULL; @@ -797,24 +596,21 @@ void R_DrawBeamFollow( BEAM *pbeam, float frametime ) VectorSubtract( particles->org, pbeam->source, delta ); div = VectorLength( delta ); - if( div >= 32 && cl_free_particles ) + if( div >= 32 ) { - pnew = cl_free_particles; - cl_free_particles = pnew->next; + pnew = gEngfuncs.CL_AllocParticleFast(); } } - else if( cl_free_particles ) + else { - pnew = cl_free_particles; - cl_free_particles = pnew->next; - div = 0; + pnew = gEngfuncs.CL_AllocParticleFast(); } } if( pnew ) { VectorCopy( pbeam->source, pnew->org ); - pnew->die = cl.time + pbeam->amplitude; + pnew->die = gpGlobals->time + pbeam->amplitude; VectorClear( pnew->vel ); pnew->next = particles; @@ -861,7 +657,7 @@ void R_DrawBeamFollow( BEAM *pbeam, float frametime ) VectorMA( delta, -pbeam->width, normal, last2 ); div = 1.0 / pbeam->amplitude; - fraction = ( pbeam->die - cl.time ) * div; + fraction = ( pbeam->die - gpGlobals->time ) * div; vLast = 0.0; vStep = 1.0; @@ -894,7 +690,7 @@ void R_DrawBeamFollow( BEAM *pbeam, float frametime ) if( particles->next != NULL ) { - fraction = (particles->die - cl.time) * div; + fraction = (particles->die - gpGlobals->time) * div; } else { @@ -975,11 +771,11 @@ 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? - if( !Mod_BoxVisible( screen, tmp, Mod_GetCurrentVis( )) || R_CullBox( screen, tmp )) + if( !gEngfuncs.Mod_BoxVisible( screen, tmp, Mod_GetCurrentVis( )) || R_CullBox( screen, tmp )) { return; } @@ -1045,6 +841,98 @@ void R_DrawRing( vec3_t source, vec3_t delta, float width, float amplitude, floa } } +/* +============== +R_BeamComputePoint + +compute attachment point for beam +============== +*/ +static qboolean R_BeamComputePoint( int beamEnt, vec3_t pt ) +{ + cl_entity_t *ent; + int attach; + + ent = gEngfuncs.R_BeamGetEntity( beamEnt ); + + if( beamEnt < 0 ) + attach = BEAMENT_ATTACHMENT( -beamEnt ); + else attach = BEAMENT_ATTACHMENT( beamEnt ); + + if( !ent ) + { + gEngfuncs.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 == ENGINE_GET_PARM( PARM_PLAYER_INDEX ) ) + { + vec3_t simorg; + gEngfuncs.GetPredictedOrigin( simorg ); + VectorCopy( 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 = gEngfuncs.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 = gEngfuncs.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 = gpGlobals->time; + return false; + } + else + { + return false; + } + } + + if( FBitSet( pbeam->flags, FBEAM_STARTENTITY ) && !FBitSet( pbeam->flags, FBEAM_STARTVISIBLE )) + return false; + return true; +} + + /* ============== R_BeamDraw @@ -1057,13 +945,13 @@ void R_BeamDraw( BEAM *pbeam, float frametime ) model_t *model; vec3_t delta; - model = CL_ModelHandle( pbeam->modelIndex ); + model = gEngfuncs.pfnGetModelByIndex( pbeam->modelIndex ); SetBits( pbeam->flags, FBEAM_ISACTIVE ); if( !model || model->type != mod_sprite ) { pbeam->flags &= ~FBEAM_ISACTIVE; // force to ignore - pbeam->die = cl.time; + pbeam->die = gpGlobals->time; return; } @@ -1121,7 +1009,7 @@ void R_BeamDraw( BEAM *pbeam, float frametime ) if( pbeam->flags & ( FBEAM_FADEIN|FBEAM_FADEOUT )) { // update life cycle - pbeam->t = pbeam->freq + ( pbeam->die - cl.time ); + pbeam->t = pbeam->freq + ( pbeam->die - gpGlobals->time ); if( pbeam->t != 0.0f ) pbeam->t = 1.0f - pbeam->freq / pbeam->t; } @@ -1169,7 +1057,7 @@ void R_BeamDraw( BEAM *pbeam, float frametime ) TriRenderMode( FBitSet( pbeam->flags, FBEAM_SOLID ) ? kRenderNormal : kRenderTransAdd ); - if( !TriSpriteTexture( model, (int)(pbeam->frame + pbeam->frameRate * cl.time) % pbeam->frameCount )) + if( !TriSpriteTexture( model, (int)(pbeam->frame + pbeam->frameRate * gpGlobals->time) % pbeam->frameCount )) { ClearBits( pbeam->flags, FBEAM_ISACTIVE ); return; @@ -1180,9 +1068,9 @@ void R_BeamDraw( BEAM *pbeam, float frametime ) cl_entity_t *pStart; // XASH SPECIFIC: get brightness from head entity - pStart = R_BeamGetEntity( pbeam->startEntity ); + pStart = gEngfuncs.R_BeamGetEntity( pbeam->startEntity ); if( pStart && pStart->curstate.rendermode != kRenderNormal ) - pbeam->brightness = CL_FxBlend( pStart ) / 255.0f; + pbeam->brightness = gEngfuncs.CL_FxBlend( pStart ) / 255.0f; } if( FBitSet( pbeam->flags, FBEAM_FADEIN )) @@ -1231,8 +1119,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 = gEngfuncs.pfnGetModelByIndex( 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 * gpGlobals->time; + pbeam->die = life + gpGlobals->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 @@ -1244,7 +1190,7 @@ void R_BeamDrawCustomEntity( cl_entity_t *ent ) { BEAM beam; float amp = ent->curstate.body / 100.0f; - float blend = CL_FxBlend( ent ) / 255.0f; + float blend = gEngfuncs.CL_FxBlend( ent ) / 255.0f; float r, g, b; int beamFlags; @@ -1303,175 +1249,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,15 +1257,11 @@ CL_DrawBeams draw beam loop ============== */ -void CL_DrawBeams( int fTrans ) +void CL_DrawBeams( int fTrans, BEAM *active_beams ) { - BEAM *pBeam, *pNext; - BEAM *pPrev = NULL; + BEAM *pBeam; int i, flags; - if( !CVAR_TO_BOOL( cl_draw_beams )) - return; - pglShadeModel( GL_SMOOTH ); pglDepthMask( fTrans ? GL_FALSE : GL_TRUE ); @@ -1512,508 +1285,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; + R_BeamDraw( pBeam, gpGlobals->time - gpGlobals->oldtime ); } 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 new file mode 100644 index 00000000..ecb6902d --- /dev/null +++ b/ref_gl/gl_context.c @@ -0,0 +1,553 @@ +/* +vid_sdl.c - SDL vid component +Copyright (C) 2018 a1batross + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + +#include "gl_local.h" +#include "gl_export.h" + +ref_api_t gEngfuncs; +ref_globals_t *gpGlobals; + +static void R_ClearScreen( void ) +{ + pglClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); + pglClear( GL_COLOR_BUFFER_BIT ); +} + +static qboolean IsNormalPass( void ) +{ + return RP_NORMALPASS(); +} + +static void R_IncrementSpeedsCounter( int type ) +{ + switch( type ) + { + case RS_ACTIVE_TENTS: + r_stats.c_active_tents_count++; + break; + default: + gEngfuncs.Host_Error( "R_IncrementSpeedsCounter: unsupported type %d\n", type ); + } +} + +static const byte *R_GetTextureOriginalBuffer( unsigned int idx ) +{ + gl_texture_t *glt = R_GetTexture( idx ); + + if( !glt || !glt->original || !glt->original->buffer ) + return NULL; + + return glt->original->buffer; +} + +static int R_GetBuiltinTexture( enum ref_shared_texture_e type ) +{ + switch( type ) + { + case REF_DEFAULT_TEXTURE: return tr.defaultTexture; + case REF_GRAY_TEXTURE: return tr.grayTexture; + case REF_WHITE_TEXTURE: return tr.whiteTexture; + case REF_SOLIDSKY_TEXTURE: return tr.solidskyTexture; + case REF_ALPHASKY_TEXTURE: return tr.alphaskyTexture; + default: gEngfuncs.Host_Error( "R_GetBuiltinTexture: unsupported type %d\n", type ); + } + + return 0; +} + +static void R_FreeSharedTexture( enum ref_shared_texture_e type ) +{ + int num = 0; + + switch( type ) + { + case REF_SOLIDSKY_TEXTURE: + num = tr.solidskyTexture; + tr.solidskyTexture = 0; + break; + case REF_ALPHASKY_TEXTURE: + num = tr.alphaskyTexture; + tr.alphaskyTexture = 0; + break; + case REF_DEFAULT_TEXTURE: + case REF_GRAY_TEXTURE: + case REF_WHITE_TEXTURE: + gEngfuncs.Host_Error( "R_FreeSharedTexture: invalid type %d\n", type ); + default: gEngfuncs.Host_Error( "R_FreeSharedTexture: unsupported type %d\n", type ); + } + + GL_FreeTexture( num ); +} + +/* +============= +CL_FillRGBA + +============= +*/ +static void CL_FillRGBA( float _x, float _y, float _w, float _h, int r, int g, int b, int a ) +{ + pglDisable( GL_TEXTURE_2D ); + pglEnable( GL_BLEND ); + pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + pglBlendFunc( GL_SRC_ALPHA, GL_ONE ); + pglColor4f( r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f ); + + pglBegin( GL_QUADS ); + pglVertex2f( _x, _y ); + pglVertex2f( _x + _w, _y ); + pglVertex2f( _x + _w, _y + _h ); + pglVertex2f( _x, _y + _h ); + pglEnd (); + + pglColor3f( 1.0f, 1.0f, 1.0f ); + pglEnable( GL_TEXTURE_2D ); + pglDisable( GL_BLEND ); +} + +/* +============= +pfnFillRGBABlend + +============= +*/ +static void GAME_EXPORT CL_FillRGBABlend( float _x, float _y, float _w, float _h, int r, int g, int b, int a ) +{ + pglDisable( GL_TEXTURE_2D ); + pglEnable( GL_BLEND ); + pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + pglColor4f( r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f ); + + pglBegin( GL_QUADS ); + pglVertex2f( _x, _y ); + pglVertex2f( _x + _w, _y ); + pglVertex2f( _x + _w, _y + _h ); + pglVertex2f( _x, _y + _h ); + pglEnd (); + + pglColor3f( 1.0f, 1.0f, 1.0f ); + pglEnable( GL_TEXTURE_2D ); + pglDisable( GL_BLEND ); +} + +static void Mod_LoadModel( modtype_t desiredType, model_t *mod, const byte *buf, qboolean *loaded, int flags ) +{ + switch( desiredType ) + { + case mod_studio: + // Mod_LoadStudioModel( mod, buf, loaded ); + break; + case mod_sprite: + Mod_LoadSpriteModel( mod, buf, loaded, flags ); + break; + case mod_alias: + Mod_LoadAliasModel( mod, buf, loaded ); + break; + case mod_brush: + // Mod_LoadBrushModel( mod, buf, loaded ); + break; + + default: gEngfuncs.Host_Error( "Mod_LoadModel: unsupported type %d\n", mod->type ); + } +} + +void Mod_BrushUnloadTextures( model_t *mod ) +{ + int i; + + for( i = 0; i < mod->numtextures; i++ ) + { + texture_t *tx = mod->textures[i]; + if( !tx || tx->gl_texturenum == tr.defaultTexture ) + continue; // free slot + + GL_FreeTexture( tx->gl_texturenum ); // main texture + GL_FreeTexture( tx->fb_texturenum ); // luma texture + } +} + +void Mod_UnloadTextures( model_t *mod ) +{ + Assert( mod != NULL ); + + switch( mod->type ) + { + case mod_studio: + Mod_StudioUnloadTextures( mod->cache.data ); + break; + case mod_alias: + Mod_AliasUnloadTextures( mod->cache.data ); + break; + case mod_brush: + Mod_BrushUnloadTextures( mod ); + break; + case mod_sprite: + Mod_SpriteUnloadTextures( mod->cache.data ); + break; + default: gEngfuncs.Host_Error( "Mod_UnloadModel: unsupported type %d\n", mod->type ); + } +} + +qboolean Mod_ProcessRenderData( model_t *mod, qboolean create, const byte *buf ) +{ + qboolean loaded = true; + + if( create ) + { + + + switch( mod->type ) + { + case mod_studio: + // Mod_LoadStudioModel( mod, buf, loaded ); + break; + case mod_sprite: + Mod_LoadSpriteModel( mod, buf, &loaded, mod->numtexinfo ); + break; + case mod_alias: + Mod_LoadAliasModel( mod, buf, &loaded ); + break; + case mod_brush: + // Mod_LoadBrushModel( mod, buf, loaded ); + break; + + default: gEngfuncs.Host_Error( "Mod_LoadModel: unsupported type %d\n", mod->type ); + } + } + + if( loaded && gEngfuncs.drawFuncs->Mod_ProcessUserData ) + gEngfuncs.drawFuncs->Mod_ProcessUserData( mod, create, buf ); + + if( !create ) + Mod_UnloadTextures( mod ); + + return loaded; +} + +static int GL_RefGetParm( int parm, int arg ) +{ + gl_texture_t *glt; + + switch( parm ) + { + case PARM_TEX_WIDTH: + glt = R_GetTexture( arg ); + return glt->width; + case PARM_TEX_HEIGHT: + glt = R_GetTexture( arg ); + return glt->height; + case PARM_TEX_SRC_WIDTH: + glt = R_GetTexture( arg ); + return glt->srcWidth; + case PARM_TEX_SRC_HEIGHT: + glt = R_GetTexture( arg ); + return glt->srcHeight; + case PARM_TEX_GLFORMAT: + glt = R_GetTexture( arg ); + return glt->format; + case PARM_TEX_ENCODE: + glt = R_GetTexture( arg ); + return glt->encode; + case PARM_TEX_MIPCOUNT: + glt = R_GetTexture( arg ); + return glt->numMips; + case PARM_TEX_DEPTH: + glt = R_GetTexture( arg ); + return glt->depth; + case PARM_TEX_SKYBOX: + Assert( arg >= 0 && arg < 6 ); + return tr.skyboxTextures[arg]; + case PARM_TEX_SKYTEXNUM: + return tr.skytexturenum; + case PARM_TEX_LIGHTMAP: + arg = bound( 0, arg, MAX_LIGHTMAPS - 1 ); + return tr.lightmapTextures[arg]; + case PARM_WIDESCREEN: + return gpGlobals->wideScreen; + case PARM_FULLSCREEN: + return gpGlobals->fullScreen; + case PARM_SCREEN_WIDTH: + return gpGlobals->width; + case PARM_SCREEN_HEIGHT: + return gpGlobals->height; + case PARM_TEX_TARGET: + glt = R_GetTexture( arg ); + return glt->target; + case PARM_TEX_TEXNUM: + glt = R_GetTexture( arg ); + return glt->texnum; + case PARM_TEX_FLAGS: + glt = R_GetTexture( arg ); + return glt->flags; + case PARM_ACTIVE_TMU: + return glState.activeTMU; + case PARM_LIGHTSTYLEVALUE: + arg = bound( 0, arg, MAX_LIGHTSTYLES - 1 ); + return tr.lightstylevalue[arg]; + case PARM_MAX_IMAGE_UNITS: + return GL_MaxTextureUnits(); + case PARM_REBUILD_GAMMA: + return glConfig.softwareGammaUpdate; + case PARM_SURF_SAMPLESIZE: + if( arg >= 0 && arg < WORLDMODEL->numsurfaces ) + return gEngfuncs.Mod_SampleSizeForFace( &WORLDMODEL->surfaces[arg] ); + return LM_SAMPLE_SIZE; + case PARM_GL_CONTEXT_TYPE: + return glConfig.context; + case PARM_GLES_WRAPPER: + return glConfig.wrapper; + case PARM_STENCIL_ACTIVE: + return glState.stencilEnabled; + case PARM_SKY_SPHERE: + return ENGINE_GET_PARM_( parm, arg ) && !tr.fCustomSkybox; + default: + return ENGINE_GET_PARM_( parm, arg ); + } + return 0; +} + +static void R_GetDetailScaleForTexture( int texture, float *xScale, float *yScale ) +{ + gl_texture_t *glt = R_GetTexture( texture ); + + if( xScale ) *xScale = glt->xscale; + if( yScale ) *yScale = glt->yscale; +} + +static void R_GetExtraParmsForTexture( int texture, byte *red, byte *green, byte *blue, byte *density ) +{ + gl_texture_t *glt = R_GetTexture( texture ); + + if( red ) *red = glt->fogParams[0]; + if( green ) *green = glt->fogParams[1]; + if( blue ) *blue = glt->fogParams[2]; + if( density ) *density = glt->fogParams[3]; +} + + +static void R_SetCurrentEntity( cl_entity_t *ent ) +{ + RI.currententity = ent; + + // set model also + if( RI.currententity != NULL ) + { + RI.currentmodel = RI.currententity->model; + } +} + +static void R_SetCurrentModel( model_t *mod ) +{ + RI.currentmodel = mod; +} + +static float R_GetFrameTime( void ) +{ + return tr.frametime; +} + +static const char *GL_TextureName( unsigned int texnum ) +{ + return R_GetTexture( texnum )->name; +} + +const byte *GL_TextureData( unsigned int texnum ) +{ + rgbdata_t *pic = R_GetTexture( texnum )->original; + + if( pic != NULL ) + return pic->buffer; + return NULL; +} + +void R_ProcessEntData( qboolean allocate ) +{ + if( !allocate ) + { + tr.draw_list->num_solid_entities = 0; + tr.draw_list->num_trans_entities = 0; + tr.draw_list->num_beam_entities = 0; + } + + if( gEngfuncs.drawFuncs->R_ProcessEntData ) + gEngfuncs.drawFuncs->R_ProcessEntData( allocate ); +} + +ref_interface_t gReffuncs = +{ + R_Init, + R_Shutdown, + + GL_SetupAttributes, + GL_OnContextCreated, + GL_InitExtensions, + GL_ClearExtensions, + + R_BeginFrame, + R_RenderScene, + R_EndFrame, + R_PushScene, + R_PopScene, + GL_BackendStartFrame, + GL_BackendEndFrame, + + R_ClearScreen, + R_AllowFog, + GL_SetRenderMode, + + R_AddEntity, + CL_AddCustomBeam, + R_ProcessEntData, + + IsNormalPass, + + R_ShowTextures, + R_ShowTree, + R_IncrementSpeedsCounter, + + R_GetTextureOriginalBuffer, + GL_LoadTextureFromBuffer, + R_GetBuiltinTexture, + R_FreeSharedTexture, + GL_ProcessTexture, + R_SetupSky, + + R_Set2DMode, + R_DrawStretchRaw, + R_DrawStretchPic, + R_DrawTileClear, + CL_FillRGBA, + CL_FillRGBABlend, + + VID_ScreenShot, + VID_CubemapShot, + + R_LightPoint, + + R_DecalShoot, + R_DecalRemoveAll, + R_CreateDecalList, + R_ClearAllDecals, + + R_StudioEstimateFrame, + R_StudioLerpMovement, + CL_InitStudioAPI, + + R_InitSkyClouds, + GL_SubdivideSurface, + CL_RunLightStyles, + + R_GetSpriteParms, + R_GetSpriteTexture, + + Mod_LoadMapSprite, + Mod_ProcessRenderData, + Mod_StudioLoadTextures, + + CL_DrawParticles, + CL_DrawTracers, + CL_DrawBeams, + R_BeamCull, + + GL_RefGetParm, + R_GetDetailScaleForTexture, + R_GetExtraParmsForTexture, + R_GetFrameTime, + + R_SetCurrentEntity, + R_SetCurrentModel, + + GL_FindTexture, + GL_TextureName, + GL_TextureData, + GL_LoadTexture, + GL_CreateTexture, + GL_LoadTextureArray, + GL_CreateTextureArray, + GL_FreeTexture, + + DrawSingleDecal, + R_DecalSetupVerts, + R_EntityRemoveDecals, + + R_UploadStretchRaw, + + GL_Bind, + GL_SelectTexture, + GL_LoadTexMatrixExt, + GL_LoadIdentityTexMatrix, + GL_CleanUpTextureUnits, + GL_TexGen, + GL_TextureTarget, + GL_SetTexCoordArrayMode, + GL_UpdateTexSize, + NULL, + NULL, + + CL_DrawParticlesExternal, + R_LightVec, + R_StudioGetTexture, + + R_RenderFrame, + GL_BuildLightmaps, + Mod_SetOrthoBounds, + R_SpeedsMessage, + Mod_GetCurrentVis, + R_NewMap, + R_ClearScene, + + TriRenderMode, + TriBegin, + TriEnd, + _TriColor4f, + TriColor4ub, + TriTexCoord2f, + TriVertex3fv, + TriVertex3f, + TriWorldToScreen, + TriFog, + R_ScreenToWorld, + TriGetMatrix, + TriFogParams, + TriCullFace, + + VGUI_DrawInit, + VGUI_DrawShutdown, + VGUI_SetupDrawingText, + VGUI_SetupDrawingRect, + VGUI_SetupDrawingImage, + VGUI_BindTexture, + VGUI_EnableTexture, + VGUI_CreateTexture, + VGUI_UploadTexture, + VGUI_UploadTextureBlock, + VGUI_DrawQuad, + VGUI_GetTextureSizes, + VGUI_GenerateTexture, +}; + +int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals ) +{ + if( version != REF_API_VERSION ) + return 0; + + // fill in our callbacks + memcpy( funcs, &gReffuncs, sizeof( ref_interface_t )); + memcpy( &gEngfuncs, engfuncs, sizeof( ref_api_t )); + gpGlobals = globals; + + return REF_API_VERSION; +} diff --git a/engine/client/gl_cull.c b/ref_gl/gl_cull.c similarity index 87% rename from engine/client/gl_cull.c rename to ref_gl/gl_cull.c index d786651e..3cd3af1d 100644 --- a/engine/client/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" @@ -56,19 +54,19 @@ R_CullModel */ int R_CullModel( cl_entity_t *e, const vec3_t absmin, const vec3_t absmax ) { - if( e == &clgame.viewent ) + if( e == gEngfuncs.GetViewModel() ) { - if( CL_IsDevOverviewMode( )) + if( ENGINE_GET_PARM( PARM_DEV_OVERVIEW )) return 1; - if( RP_NORMALPASS() && !cl.local.thirdperson && cl.viewentity == ( cl.playernum + 1 )) + if( RP_NORMALPASS() && !ENGINE_GET_PARM( PARM_THIRDPERSON ) && CL_IsViewEntityLocalPlayer()) return 0; return 1; } // local client can't view himself if camera or thirdperson is not active - if( RP_LOCALCLIENT( e ) && !cl.local.thirdperson && cl.viewentity == ( cl.playernum + 1 )) + if( RP_LOCALCLIENT( e ) && !ENGINE_GET_PARM( PARM_THIRDPERSON ) && CL_IsViewEntityLocalPlayer()) return 1; if( R_CullBox( absmin, absmax )) @@ -95,7 +93,7 @@ int R_CullSurface( msurface_t *surf, gl_frustum_t *frustum, uint clipflags ) return CULL_VISIBLE; // world surfaces can be culled by vis frame too - if( RI.currententity == clgame.entities && surf->visframe != tr.framecount ) + if( RI.currententity == gEngfuncs.GetEntityByIndex( 0 ) && surf->visframe != tr.framecount ) return CULL_VISFRAME; // only static ents can be culled by frustum @@ -110,7 +108,7 @@ int R_CullSurface( msurface_t *surf, gl_frustum_t *frustum, uint clipflags ) { vec3_t orthonormal; - if( e == clgame.entities ) orthonormal[2] = surf->plane->normal[2]; + if( e == gEngfuncs.GetEntityByIndex( 0 ) ) orthonormal[2] = surf->plane->normal[2]; else Matrix4x4_VectorRotate( RI.objectMatrix, surf->plane->normal, orthonormal ); dist = orthonormal[2]; } @@ -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 new file mode 100644 index 00000000..d21cfae5 --- /dev/null +++ b/ref_gl/gl_dbghulls.c @@ -0,0 +1,90 @@ +/* +gl_dbghulls.c - loading & handling world and brushmodels +Copyright (C) 2016 Uncle Mike + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + +#include "gl_local.h" +#include "mod_local.h" + +#define list_entry( ptr, type, member ) \ + ((type *)((char *)(ptr) - (size_t)(&((type *)0)->member))) + +// iterate over each entry in the list +#define list_for_each_entry( pos, head, member ) \ + for( pos = list_entry( (head)->next, winding_t, member ); \ + &pos->member != (head); \ + pos = list_entry( pos->member.next, winding_t, member )) + +// REFTODO: rewrite in triapi +void R_DrawWorldHull( void ) +{ + hull_model_t *hull = &WORLD->hull_models[0]; + winding_t *poly; + int i; + + if( FBitSet( r_showhull->flags, FCVAR_CHANGED )) + { + int val = bound( 0, (int)r_showhull->value, 3 ); + if( val ) gEngfuncs.Mod_CreatePolygonsForHull( val ); + ClearBits( r_showhull->flags, FCVAR_CHANGED ); + } + + if( !CVAR_TO_BOOL( r_showhull )) + return; + pglDisable( GL_TEXTURE_2D ); + + list_for_each_entry( poly, &hull->polys, chain ) + { + srand((unsigned int)poly); + pglColor3f( rand() % 256 / 255.0, rand() % 256 / 255.0, rand() % 256 / 255.0 ); + pglBegin( GL_POLYGON ); + for( i = 0; i < poly->numpoints; i++ ) + pglVertex3fv( poly->p[i] ); + pglEnd(); + } + pglEnable( GL_TEXTURE_2D ); +} + +void R_DrawModelHull( void ) +{ + hull_model_t *hull; + winding_t *poly; + int i; + + if( !CVAR_TO_BOOL( r_showhull )) + return; + + if( !RI.currentmodel || RI.currentmodel->name[0] != '*' ) + return; + + i = atoi( RI.currentmodel->name + 1 ); + if( i < 1 || i >= WORLD->num_hull_models ) + return; + + hull = &WORLD->hull_models[i]; + + pglPolygonOffset( 1.0f, 2.0 ); + pglEnable( GL_POLYGON_OFFSET_FILL ); + pglDisable( GL_TEXTURE_2D ); + list_for_each_entry( poly, &hull->polys, chain ) + { + srand((unsigned int)poly); + pglColor3f( rand() % 256 / 255.0, rand() % 256 / 255.0, rand() % 256 / 255.0 ); + pglBegin( GL_POLYGON ); + for( i = 0; i < poly->numpoints; i++ ) + pglVertex3fv( poly->p[i] ); + pglEnd(); + } + pglEnable( GL_TEXTURE_2D ); + pglDisable( GL_POLYGON_OFFSET_FILL ); +} diff --git a/engine/client/gl_decals.c b/ref_gl/gl_decals.c similarity index 96% rename from engine/client/gl_decals.c rename to ref_gl/gl_decals.c index 0c7ea2c6..c2c1cc53 100644 --- a/engine/client/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" @@ -77,7 +75,7 @@ static void R_DecalUnlink( decal_t *pdecal ) else { tmp = pdecal->psurface->pdecals; - if( !tmp ) Host_Error( "D_DecalUnlink: bad decal list\n" ); + if( !tmp ) gEngfuncs.Host_Error( "D_DecalUnlink: bad decal list\n" ); while( tmp->pnext ) { @@ -400,7 +398,7 @@ static void R_DecalVertsLight( float *v, msurface_t *surf, int vertCount ) float sample_size; int j; - sample_size = Mod_SampleSizeForFace( surf ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( surf ); tex = surf->texinfo; for( j = 0; j < vertCount; j++, v += VERTEXSIZE ) @@ -513,7 +511,7 @@ creates mesh for decal on first rendering glpoly_t *R_DecalCreatePoly( decalinfo_t *decalinfo, decal_t *pdecal, msurface_t *surf ) { int lnumverts; - glpoly_t *poly; + glpoly_t *poly; float *v; int i; @@ -524,7 +522,8 @@ glpoly_t *R_DecalCreatePoly( decalinfo_t *decalinfo, decal_t *pdecal, msurface_t if( !lnumverts ) return NULL; // probably this never happens // allocate glpoly - poly = Mem_Calloc( com_studiocache, sizeof( glpoly_t ) + ( lnumverts - 4 ) * VERTEXSIZE * sizeof( float )); + // REFTODO: com_studiocache pool! + poly = Mem_Calloc( r_temppool, sizeof( glpoly_t ) + ( lnumverts - 4 ) * VERTEXSIZE * sizeof( float )); poly->next = pdecal->polys; poly->flags = surf->flags; pdecal->polys = poly; @@ -619,9 +618,10 @@ void R_DecalSurface( msurface_t *surf, decalinfo_t *decalinfo ) decal_t *decal = surf->pdecals; vec4_t textureU, textureV; float s, t, w, h; + connstate_t state = ENGINE_GET_PARM( PARM_CONNSTATE ); // we in restore mode - if( cls.state == ca_connected || cls.state == ca_validate ) + if( state == ca_connected || state == ca_validate ) { // NOTE: we may have the decal on this surface that come from another level. // check duplicate with same position and texture @@ -760,27 +760,27 @@ void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos if( textureIndex <= 0 || textureIndex >= MAX_TEXTURES ) { - Con_Printf( S_ERROR "Decal has invalid texture!\n" ); + gEngfuncs.Con_Printf( S_ERROR "Decal has invalid texture!\n" ); return; } if( entityIndex > 0 ) { - ent = CL_GetEntityByIndex( entityIndex ); + ent = gEngfuncs.GetEntityByIndex( entityIndex ); - if( modelIndex > 0 ) model = CL_ModelHandle( modelIndex ); - else if( ent != NULL ) model = CL_ModelHandle( ent->curstate.modelindex ); + if( modelIndex > 0 ) model = gEngfuncs.pfnGetModelByIndex( modelIndex ); + else if( ent != NULL ) model = gEngfuncs.pfnGetModelByIndex( ent->curstate.modelindex ); else return; } else if( modelIndex > 0 ) - model = CL_ModelHandle( modelIndex ); - else model = cl.worldmodel; + model = gEngfuncs.pfnGetModelByIndex( modelIndex ); + else model = WORLDMODEL; if( !model ) return; if( model->type != mod_brush ) { - Con_Printf( S_ERROR "Decals must hit mod_brush!\n" ); + gEngfuncs.Con_Printf( S_ERROR "Decals must hit mod_brush!\n" ); return; } @@ -1163,7 +1163,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++ ) { @@ -1195,9 +1195,9 @@ int R_CreateDecalList( decallist_t *pList ) total = DecalListAdd( pList, total ); } - if( clgame.drawFuncs.R_CreateStudioDecalList ) + if( gEngfuncs.drawFuncs->R_CreateStudioDecalList ) { - total += clgame.drawFuncs.R_CreateStudioDecalList( pList, total ); + total += gEngfuncs.drawFuncs->R_CreateStudioDecalList( pList, total ); } } @@ -1279,8 +1279,8 @@ void R_ClearAllDecals( void ) R_DecalUnlink( pdecal ); } - if( clgame.drawFuncs.R_ClearStudioDecals ) + if( gEngfuncs.drawFuncs->R_ClearStudioDecals ) { - clgame.drawFuncs.R_ClearStudioDecals(); + gEngfuncs.drawFuncs->R_ClearStudioDecals(); } } diff --git a/engine/client/gl_draw.c b/ref_gl/gl_draw.c similarity index 90% rename from engine/client/gl_draw.c rename to ref_gl/gl_draw.c index 63178b26..d2494343 100644 --- a/engine/client/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" /* @@ -91,16 +89,16 @@ This repeats a 64*64 tile graphic to fill the screen around a sized down refresh window. ============= */ -void R_DrawTileClear( int x, int y, int w, int h ) +void R_DrawTileClear( int texnum, int x, int y, int w, int h ) { float tw, th; gl_texture_t *glt; GL_SetRenderMode( kRenderNormal ); pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); - GL_Bind( XASH_TEXTURE0, cls.tileImage ); + GL_Bind( XASH_TEXTURE0, texnum ); - glt = R_GetTexture( cls.tileImage ); + glt = R_GetTexture( texnum ); tw = glt->srcWidth; th = glt->srcHeight; @@ -147,9 +145,9 @@ void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, c } if( cols > glConfig.max_2d_texture_size ) - Host_Error( "R_DrawStretchRaw: size %i exceeds hardware limits\n", cols ); + gEngfuncs.Host_Error( "R_DrawStretchRaw: size %i exceeds hardware limits\n", cols ); if( rows > glConfig.max_2d_texture_size ) - Host_Error( "R_DrawStretchRaw: size %i exceeds hardware limits\n", rows ); + gEngfuncs.Host_Error( "R_DrawStretchRaw: size %i exceeds hardware limits\n", rows ); pglDisable( GL_BLEND ); pglDisable( GL_ALPHA_TEST ); @@ -222,9 +220,9 @@ void R_UploadStretchRaw( int texture, int cols, int rows, int width, int height, } if( cols > glConfig.max_2d_texture_size ) - Host_Error( "R_UploadStretchRaw: size %i exceeds hardware limits\n", cols ); + gEngfuncs.Host_Error( "R_UploadStretchRaw: size %i exceeds hardware limits\n", cols ); if( rows > glConfig.max_2d_texture_size ) - Host_Error( "R_UploadStretchRaw: size %i exceeds hardware limits\n", rows ); + gEngfuncs.Host_Error( "R_UploadStretchRaw: size %i exceeds hardware limits\n", rows ); tex = R_GetTexture( texture ); GL_Bind( GL_KEEP_UNIT, texture ); @@ -248,10 +246,10 @@ void R_Set2DMode( qboolean enable ) return; // set 2D virtual screen size - pglViewport( 0, 0, glState.width, glState.height ); + pglViewport( 0, 0, gpGlobals->width, gpGlobals->height ); pglMatrixMode( GL_PROJECTION ); pglLoadIdentity(); - pglOrtho( 0, glState.width, glState.height, 0, -99999, 99999 ); + pglOrtho( 0, gpGlobals->width, gpGlobals->height, 0, -99999, 99999 ); pglMatrixMode( GL_MODELVIEW ); pglLoadIdentity(); @@ -280,4 +278,4 @@ void R_Set2DMode( qboolean enable ) GL_Cull( GL_FRONT ); } -} \ No newline at end of file +} diff --git a/engine/client/gl_export.h b/ref_gl/gl_export.h similarity index 100% rename from engine/client/gl_export.h rename to ref_gl/gl_export.h diff --git a/engine/client/gl_frustum.c b/ref_gl/gl_frustum.c similarity index 99% rename from engine/client/gl_frustum.c rename to ref_gl/gl_frustum.c index aa1c0a5d..64c56118 100644 --- a/engine/client/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/engine/client/gl_frustum.h b/ref_gl/gl_frustum.h similarity index 100% rename from engine/client/gl_frustum.h rename to ref_gl/gl_frustum.h diff --git a/engine/client/gl_image.c b/ref_gl/gl_image.c similarity index 89% rename from engine/client/gl_image.c rename to ref_gl/gl_image.c index 048e9910..46f56856 100644 --- a/engine/client/gl_image.c +++ b/ref_gl/gl_image.c @@ -13,10 +13,9 @@ 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) static gl_texture_t gl_textures[MAX_TEXTURES]; @@ -299,17 +298,17 @@ void R_SetTextureParameters( void ) if( GL_Support( GL_ANISOTROPY_EXT )) { if( gl_texture_anisotropy->value > glConfig.max_texture_anisotropy ) - Cvar_SetValue( "gl_anisotropy", glConfig.max_texture_anisotropy ); + gEngfuncs.Cvar_SetValue( "gl_anisotropy", glConfig.max_texture_anisotropy ); else if( gl_texture_anisotropy->value < 1.0f ) - Cvar_SetValue( "gl_anisotropy", 1.0f ); + gEngfuncs.Cvar_SetValue( "gl_anisotropy", 1.0f ); } if( GL_Support( GL_TEXTURE_LOD_BIAS )) { if( gl_texture_lodbias->value < -glConfig.max_texture_lod_bias ) - Cvar_SetValue( "gl_texture_lodbias", -glConfig.max_texture_lod_bias ); + gEngfuncs.Cvar_SetValue( "gl_texture_lodbias", -glConfig.max_texture_lod_bias ); else if( gl_texture_lodbias->value > glConfig.max_texture_lod_bias ) - Cvar_SetValue( "gl_texture_lodbias", glConfig.max_texture_lod_bias ); + gEngfuncs.Cvar_SetValue( "gl_texture_lodbias", glConfig.max_texture_lod_bias ); } ClearBits( gl_texture_anisotropy->flags, FCVAR_CHANGED ); @@ -462,7 +461,7 @@ static size_t GL_CalcTextureSize( GLenum format, int width, int height, int dept size = width * height * depth * 4; break; default: - Host_Error( "GL_CalcTextureSize: bad texture internal format (%u)\n", format ); + gEngfuncs.Host_Error( "GL_CalcTextureSize: bad texture internal format (%u)\n", format ); break; } @@ -879,7 +878,7 @@ byte *GL_ApplyFilter( const byte *source, int width, int height ) byte *out = (byte *)source; int i; - if( Host_IsQuakeCompatible() || glConfig.max_multisamples > 1 ) + if( ENGINE_GET_PARM( PARM_QUAKE_COMPATIBLE ) || glConfig.max_multisamples > 1 ) return in; for( i = 0; source && i < width * height; i++, in += 4 ) @@ -986,7 +985,7 @@ static void GL_TextureImageRAW( gl_texture_t *tex, GLint side, GLint level, GLin { GLuint cubeTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB; qboolean subImage = FBitSet( tex->flags, TF_IMG_UPLOADED ); - GLenum inFormat = PFDesc[type].glFormat; + GLenum inFormat = gEngfuncs.Image_GetPFDesc(type)->glFormat; GLint dataType = GL_UNSIGNED_BYTE; Assert( tex != NULL ); @@ -1065,7 +1064,7 @@ static void GL_CheckTexImageError( gl_texture_t *tex ) // catch possible errors if( CVAR_TO_BOOL( gl_check_errors ) && ( err = pglGetError()) != GL_NO_ERROR ) - Con_Printf( S_OPENGL_ERROR "%s while uploading %s [%s]\n", GL_ErrorString( err ), tex->name, GL_TargetToString( tex->target )); + gEngfuncs.Con_Printf( S_OPENGL_ERROR "%s while uploading %s [%s]\n", GL_ErrorString( err ), tex->name, GL_TargetToString( tex->target )); } /* @@ -1093,7 +1092,7 @@ static qboolean GL_UploadTexture( gl_texture_t *tex, rgbdata_t *pic ) // make sure what target is correct if( tex->target == GL_NONE ) { - Con_DPrintf( S_ERROR "GL_UploadTexture: %s is not supported by your hardware\n", tex->name ); + gEngfuncs.Con_DPrintf( S_ERROR "GL_UploadTexture: %s is not supported by your hardware\n", tex->name ); return false; } @@ -1108,7 +1107,7 @@ static qboolean GL_UploadTexture( gl_texture_t *tex, rgbdata_t *pic ) if(( pic->width * pic->height ) & 3 ) { // will be resampled, just tell me for debug targets - Con_Reportf( "GL_UploadTexture: %s s&3 [%d x %d]\n", tex->name, pic->width, pic->height ); + gEngfuncs.Con_Reportf( "GL_UploadTexture: %s s&3 [%d x %d]\n", tex->name, pic->width, pic->height ); } buf = pic->buffer; @@ -1126,7 +1125,7 @@ static qboolean GL_UploadTexture( gl_texture_t *tex, rgbdata_t *pic ) { // track the buffer bounds if( buf != NULL && buf >= bufend ) - Host_Error( "GL_UploadTexture: %s image buffer overflow\n", tex->name ); + gEngfuncs.Host_Error( "GL_UploadTexture: %s image buffer overflow\n", tex->name ); if( ImageDXT( pic->type )) { @@ -1249,14 +1248,14 @@ static void GL_ProcessImage( gl_texture_t *tex, rgbdata_t *pic ) } if( !FBitSet( tex->flags, TF_IMG_UPLOADED ) && FBitSet( tex->flags, TF_KEEP_SOURCE )) - tex->original = FS_CopyImage( pic ); // because current pic will be expanded to rgba + tex->original = gEngfuncs.FS_CopyImage( pic ); // because current pic will be expanded to rgba // we need to expand image into RGBA buffer if( pic->type == PF_INDEXED_24 || pic->type == PF_INDEXED_32 ) img_flags |= IMAGE_FORCE_RGBA; // processing image before uploading (force to rgba, make luma etc) - if( pic->buffer ) Image_Process( &pic, 0, 0, img_flags, gl_emboss_scale->value ); + if( pic->buffer ) gEngfuncs.Image_Process( &pic, 0, 0, img_flags, gl_emboss_scale->value ); if( FBitSet( tex->flags, TF_LUMINANCE )) ClearBits( pic->flags, IMAGE_HAS_COLOR ); @@ -1276,7 +1275,7 @@ qboolean GL_CheckTexName( const char *name ) // because multi-layered textures can exceed name string if( Q_strlen( name ) >= sizeof( gl_textures->name )) { - Con_Printf( S_ERROR "LoadTexture: too long name %s (%d)\n", name, Q_strlen( name )); + gEngfuncs.Con_Printf( S_ERROR "LoadTexture: too long name %s (%d)\n", name, Q_strlen( name )); return false; } @@ -1294,7 +1293,7 @@ static gl_texture_t *GL_TextureForName( const char *name ) uint hash; // find the texture in array - hash = COM_HashKey( name, TEXTURES_HASH_SIZE ); + hash = gEngfuncs.COM_HashKey( name, TEXTURES_HASH_SIZE ); for( tex = gl_texturesHashTable[hash]; tex != NULL; tex = tex->nextHash ) { @@ -1322,7 +1321,7 @@ static gl_texture_t *GL_AllocTexture( const char *name, texFlags_t flags ) if( i == gl_numTextures ) { if( gl_numTextures == MAX_TEXTURES ) - Host_Error( "GL_AllocTexture: MAX_TEXTURES limit exceeds\n" ); + gEngfuncs.Host_Error( "GL_AllocTexture: MAX_TEXTURES limit exceeds\n" ); gl_numTextures++; } @@ -1336,7 +1335,7 @@ static gl_texture_t *GL_AllocTexture( const char *name, texFlags_t flags ) tex->flags = flags; // add to hash table - tex->hashValue = COM_HashKey( name, TEXTURES_HASH_SIZE ); + tex->hashValue = gEngfuncs.COM_HashKey( name, TEXTURES_HASH_SIZE ); tex->nextHash = gl_texturesHashTable[tex->hashValue]; gl_texturesHashTable[tex->hashValue] = tex; @@ -1361,7 +1360,7 @@ static void GL_DeleteTexture( gl_texture_t *tex ) // debug if( !tex->name[0] ) { - Con_Printf( S_ERROR "GL_DeleteTexture: trying to free unnamed texture with texnum %i\n", tex->texnum ); + gEngfuncs.Con_Printf( S_ERROR "GL_DeleteTexture: trying to free unnamed texture with texnum %i\n", tex->texnum ); return; } @@ -1383,7 +1382,7 @@ static void GL_DeleteTexture( gl_texture_t *tex ) // release source if( tex->original ) - FS_FreeImage( tex->original ); + gEngfuncs.FS_FreeImage( tex->original ); pglDeleteTextures( 1, &tex->texnum ); memset( tex, 0, sizeof( *tex )); @@ -1447,9 +1446,9 @@ int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags ) SetBits( picFlags, IL_KEEP_8BIT ); // set some image flags - Image_SetForceFlags( picFlags ); + gEngfuncs.Image_SetForceFlags( picFlags ); - pic = FS_LoadImage( name, buf, size ); + pic = gEngfuncs.FS_LoadImage( name, buf, size ); if( !pic ) return 0; // couldn't loading image // allocate the new one @@ -1459,12 +1458,12 @@ int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags ) if( !GL_UploadTexture( tex, pic )) { memset( tex, 0, sizeof( gl_texture_t )); - FS_FreeImage( pic ); // release source texture + gEngfuncs.FS_FreeImage( pic ); // release source texture return 0; } GL_ApplyTextureParams( tex ); // update texture filter, wrap etc - FS_FreeImage( pic ); // release source texture + gEngfuncs.FS_FreeImage( pic ); // release source texture // NOTE: always return texnum as index in array or engine will stop work !!! return tex - gl_textures; @@ -1517,7 +1516,7 @@ int GL_LoadTextureArray( const char **names, int flags ) { size_t srcsize, dstsize, mipsize; - src = FS_LoadImage( names[i], NULL, 0 ); + src = gEngfuncs.FS_LoadImage( names[i], NULL, 0 ); if( !src ) break; // coldn't find layer if( pic ) @@ -1525,41 +1524,41 @@ int GL_LoadTextureArray( const char **names, int flags ) // mixed mode: DXT + RGB if( pic->type != src->type ) { - Con_Printf( S_ERROR "GL_LoadTextureArray: mismatch image format for %s and %s\n", names[0], names[i] ); + gEngfuncs.Con_Printf( S_ERROR "GL_LoadTextureArray: mismatch image format for %s and %s\n", names[0], names[i] ); break; } // different mipcount if( pic->numMips != src->numMips ) { - Con_Printf( S_ERROR "GL_LoadTextureArray: mismatch mip count for %s and %s\n", names[0], names[i] ); + gEngfuncs.Con_Printf( S_ERROR "GL_LoadTextureArray: mismatch mip count for %s and %s\n", names[0], names[i] ); break; } if( pic->encode != src->encode ) { - Con_Printf( S_ERROR "GL_LoadTextureArray: mismatch custom encoding for %s and %s\n", names[0], names[i] ); + gEngfuncs.Con_Printf( S_ERROR "GL_LoadTextureArray: mismatch custom encoding for %s and %s\n", names[0], names[i] ); break; } // but allow to rescale raw images if( ImageRAW( pic->type ) && ImageRAW( src->type ) && ( pic->width != src->width || pic->height != src->height )) - Image_Process( &src, pic->width, pic->height, IMAGE_RESAMPLE, 0.0f ); + gEngfuncs.Image_Process( &src, pic->width, pic->height, IMAGE_RESAMPLE, 0.0f ); if( pic->size != src->size ) { - Con_Printf( S_ERROR "GL_LoadTextureArray: mismatch image size for %s and %s\n", names[0], names[i] ); + gEngfuncs.Con_Printf( S_ERROR "GL_LoadTextureArray: mismatch image size for %s and %s\n", names[0], names[i] ); break; } } else { // create new image - pic = Mem_Malloc( host.imagepool, sizeof( rgbdata_t )); + pic = Mem_Malloc( gEngfuncs.Image_GetPool(), sizeof( rgbdata_t )); memcpy( pic, src, sizeof( rgbdata_t )); // expand pic buffer for all layers - pic->buffer = Mem_Malloc( host.imagepool, pic->size * numLayers ); + pic->buffer = Mem_Malloc( gEngfuncs.Image_GetPool(), pic->size * numLayers ); pic->depth = 0; } @@ -1575,7 +1574,7 @@ int GL_LoadTextureArray( const char **names, int flags ) srcsize += mipsize; } - FS_FreeImage( src ); + gEngfuncs.FS_FreeImage( src ); // increase layers pic->depth++; @@ -1584,8 +1583,8 @@ int GL_LoadTextureArray( const char **names, int flags ) // there were errors if( !pic || ( pic->depth != numLayers )) { - Con_Printf( S_ERROR "GL_LoadTextureArray: not all layers were loaded. Texture array is not created\n" ); - if( pic ) FS_FreeImage( pic ); + gEngfuncs.Con_Printf( S_ERROR "GL_LoadTextureArray: not all layers were loaded. Texture array is not created\n" ); + if( pic ) gEngfuncs.FS_FreeImage( pic ); return 0; } @@ -1600,12 +1599,12 @@ int GL_LoadTextureArray( const char **names, int flags ) if( !GL_UploadTexture( tex, pic )) { memset( tex, 0, sizeof( gl_texture_t )); - FS_FreeImage( pic ); // release source texture + gEngfuncs.FS_FreeImage( pic ); // release source texture return 0; } GL_ApplyTextureParams( tex ); // update texture filter, wrap etc - FS_FreeImage( pic ); // release source texture + gEngfuncs.FS_FreeImage( pic ); // release source texture // NOTE: always return texnum as index in array or engine will stop work !!! return tex - gl_textures; @@ -1633,7 +1632,7 @@ int GL_LoadTextureFromBuffer( const char *name, rgbdata_t *pic, texFlags_t flags if( update ) { if( tex == NULL ) - Host_Error( "GL_LoadTextureFromBuffer: couldn't find texture %s for update\n", name ); + gEngfuncs.Host_Error( "GL_LoadTextureFromBuffer: couldn't find texture %s for update\n", name ); SetBits( tex->flags, flags ); } else @@ -1761,21 +1760,6 @@ int GL_FindTexture( const char *name ) return 0; } -/* -================ -GL_FreeImage - -Frees image by name -================ -*/ -void GL_FreeImage( const char *name ) -{ - int texnum; - - if(( texnum = GL_FindTexture( name )) != 0 ) - GL_FreeTexture( texnum ); -} - /* ================ GL_FreeTexture @@ -1816,30 +1800,30 @@ void GL_ProcessTexture( int texnum, float gamma, int topColor, int bottomColor ) } else { - Con_Printf( S_ERROR "GL_ProcessTexture: bad operation for %s\n", image->name ); + gEngfuncs.Con_Printf( S_ERROR "GL_ProcessTexture: bad operation for %s\n", image->name ); return; } if( !image->original ) { - Con_Printf( S_ERROR "GL_ProcessTexture: no input data for %s\n", image->name ); + gEngfuncs.Con_Printf( S_ERROR "GL_ProcessTexture: no input data for %s\n", image->name ); return; } if( ImageDXT( image->original->type )) { - Con_Printf( S_ERROR "GL_ProcessTexture: can't process compressed texture %s\n", image->name ); + gEngfuncs.Con_Printf( S_ERROR "GL_ProcessTexture: can't process compressed texture %s\n", image->name ); return; } // all the operations makes over the image copy not an original - pic = FS_CopyImage( image->original ); - Image_Process( &pic, topColor, bottomColor, flags, 0.0f ); + pic = gEngfuncs.FS_CopyImage( image->original ); + gEngfuncs.Image_Process( &pic, topColor, bottomColor, flags, 0.0f ); GL_UploadTexture( image, pic ); GL_ApplyTextureParams( image ); // update texture filter, wrap etc - FS_FreeImage( pic ); + gEngfuncs.FS_FreeImage( pic ); } /* @@ -1977,8 +1961,8 @@ void R_TextureList_f( void ) gl_texture_t *image; int i, texCount, bytes = 0; - Con_Printf( "\n" ); - Con_Printf( " -id- -w- -h- -size- -fmt- -type- -data- -encode- -wrap- -depth- -name--------\n" ); + gEngfuncs.Con_Printf( "\n" ); + gEngfuncs.Con_Printf( " -id- -w- -h- -size- -fmt- -type- -data- -encode- -wrap- -depth- -name--------\n" ); for( i = texCount = 0, image = gl_textures; i < gl_numTextures; i++, image++ ) { @@ -1987,192 +1971,192 @@ void R_TextureList_f( void ) bytes += image->size; texCount++; - Con_Printf( "%4i: ", i ); - Con_Printf( "%4i %4i ", image->width, image->height ); - Con_Printf( "%12s ", Q_memprint( image->size )); + gEngfuncs.Con_Printf( "%4i: ", i ); + gEngfuncs.Con_Printf( "%4i %4i ", image->width, image->height ); + gEngfuncs.Con_Printf( "%12s ", Q_memprint( image->size )); switch( image->format ) { case GL_COMPRESSED_RGBA_ARB: - Con_Printf( "CRGBA " ); + gEngfuncs.Con_Printf( "CRGBA " ); break; case GL_COMPRESSED_RGB_ARB: - Con_Printf( "CRGB " ); + gEngfuncs.Con_Printf( "CRGB " ); break; case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: - Con_Printf( "CLA " ); + gEngfuncs.Con_Printf( "CLA " ); break; case GL_COMPRESSED_LUMINANCE_ARB: - Con_Printf( "CL " ); + gEngfuncs.Con_Printf( "CL " ); break; case GL_COMPRESSED_ALPHA_ARB: - Con_Printf( "CA " ); + gEngfuncs.Con_Printf( "CA " ); break; case GL_COMPRESSED_INTENSITY_ARB: - Con_Printf( "CI " ); + gEngfuncs.Con_Printf( "CI " ); break; case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - Con_Printf( "DXT1c " ); + gEngfuncs.Con_Printf( "DXT1c " ); break; case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - Con_Printf( "DXT1a " ); + gEngfuncs.Con_Printf( "DXT1a " ); break; case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - Con_Printf( "DXT3 " ); + gEngfuncs.Con_Printf( "DXT3 " ); break; case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - Con_Printf( "DXT5 " ); + gEngfuncs.Con_Printf( "DXT5 " ); break; case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: - Con_Printf( "ATI2 " ); + gEngfuncs.Con_Printf( "ATI2 " ); break; case GL_RGBA: - Con_Printf( "RGBA " ); + gEngfuncs.Con_Printf( "RGBA " ); break; case GL_RGBA8: - Con_Printf( "RGBA8 " ); + gEngfuncs.Con_Printf( "RGBA8 " ); break; case GL_RGBA4: - Con_Printf( "RGBA4 " ); + gEngfuncs.Con_Printf( "RGBA4 " ); break; case GL_RGB: - Con_Printf( "RGB " ); + gEngfuncs.Con_Printf( "RGB " ); break; case GL_RGB8: - Con_Printf( "RGB8 " ); + gEngfuncs.Con_Printf( "RGB8 " ); break; case GL_RGB5: - Con_Printf( "RGB5 " ); + gEngfuncs.Con_Printf( "RGB5 " ); break; case GL_LUMINANCE4_ALPHA4: - Con_Printf( "L4A4 " ); + gEngfuncs.Con_Printf( "L4A4 " ); break; case GL_LUMINANCE_ALPHA: case GL_LUMINANCE8_ALPHA8: - Con_Printf( "L8A8 " ); + gEngfuncs.Con_Printf( "L8A8 " ); break; case GL_LUMINANCE4: - Con_Printf( "L4 " ); + gEngfuncs.Con_Printf( "L4 " ); break; case GL_LUMINANCE: case GL_LUMINANCE8: - Con_Printf( "L8 " ); + gEngfuncs.Con_Printf( "L8 " ); break; case GL_ALPHA8: - Con_Printf( "A8 " ); + gEngfuncs.Con_Printf( "A8 " ); break; case GL_INTENSITY8: - Con_Printf( "I8 " ); + gEngfuncs.Con_Printf( "I8 " ); break; case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT24: - Con_Printf( "DPTH24" ); + gEngfuncs.Con_Printf( "DPTH24" ); break; case GL_DEPTH_COMPONENT32F: - Con_Printf( "DPTH32" ); + gEngfuncs.Con_Printf( "DPTH32" ); break; case GL_LUMINANCE16F_ARB: - Con_Printf( "L16F " ); + gEngfuncs.Con_Printf( "L16F " ); break; case GL_LUMINANCE32F_ARB: - Con_Printf( "L32F " ); + gEngfuncs.Con_Printf( "L32F " ); break; case GL_LUMINANCE_ALPHA16F_ARB: - Con_Printf( "LA16F " ); + gEngfuncs.Con_Printf( "LA16F " ); break; case GL_LUMINANCE_ALPHA32F_ARB: - Con_Printf( "LA32F " ); + gEngfuncs.Con_Printf( "LA32F " ); break; case GL_RG16F: - Con_Printf( "RG16F " ); + gEngfuncs.Con_Printf( "RG16F " ); break; case GL_RG32F: - Con_Printf( "RG32F " ); + gEngfuncs.Con_Printf( "RG32F " ); break; case GL_RGB16F_ARB: - Con_Printf( "RGB16F" ); + gEngfuncs.Con_Printf( "RGB16F" ); break; case GL_RGB32F_ARB: - Con_Printf( "RGB32F" ); + gEngfuncs.Con_Printf( "RGB32F" ); break; case GL_RGBA16F_ARB: - Con_Printf( "RGBA16F" ); + gEngfuncs.Con_Printf( "RGBA16F" ); break; case GL_RGBA32F_ARB: - Con_Printf( "RGBA32F" ); + gEngfuncs.Con_Printf( "RGBA32F" ); break; default: - Con_Printf( " ^1ERROR^7 " ); + gEngfuncs.Con_Printf( " ^1ERROR^7 " ); break; } switch( image->target ) { case GL_TEXTURE_1D: - Con_Printf( " 1D " ); + gEngfuncs.Con_Printf( " 1D " ); break; case GL_TEXTURE_2D: - Con_Printf( " 2D " ); + gEngfuncs.Con_Printf( " 2D " ); break; case GL_TEXTURE_3D: - Con_Printf( " 3D " ); + gEngfuncs.Con_Printf( " 3D " ); break; case GL_TEXTURE_CUBE_MAP_ARB: - Con_Printf( "CUBE " ); + gEngfuncs.Con_Printf( "CUBE " ); break; case GL_TEXTURE_RECTANGLE_EXT: - Con_Printf( "RECT " ); + gEngfuncs.Con_Printf( "RECT " ); break; case GL_TEXTURE_2D_ARRAY_EXT: - Con_Printf( "ARRAY " ); + gEngfuncs.Con_Printf( "ARRAY " ); break; default: - Con_Printf( "???? " ); + gEngfuncs.Con_Printf( "???? " ); break; } if( image->flags & TF_NORMALMAP ) - Con_Printf( "normal " ); - else Con_Printf( "diffuse " ); + gEngfuncs.Con_Printf( "normal " ); + else gEngfuncs.Con_Printf( "diffuse " ); switch( image->encode ) { case DXT_ENCODE_COLOR_YCoCg: - Con_Printf( "YCoCg " ); + gEngfuncs.Con_Printf( "YCoCg " ); break; case DXT_ENCODE_NORMAL_AG_ORTHO: - Con_Printf( "ortho " ); + gEngfuncs.Con_Printf( "ortho " ); break; case DXT_ENCODE_NORMAL_AG_STEREO: - Con_Printf( "stereo " ); + gEngfuncs.Con_Printf( "stereo " ); break; case DXT_ENCODE_NORMAL_AG_PARABOLOID: - Con_Printf( "parabolic " ); + gEngfuncs.Con_Printf( "parabolic " ); break; case DXT_ENCODE_NORMAL_AG_QUARTIC: - Con_Printf( "quartic " ); + gEngfuncs.Con_Printf( "quartic " ); break; case DXT_ENCODE_NORMAL_AG_AZIMUTHAL: - Con_Printf( "azimuthal " ); + gEngfuncs.Con_Printf( "azimuthal " ); break; default: - Con_Printf( "default " ); + gEngfuncs.Con_Printf( "default " ); break; } if( image->flags & TF_CLAMP ) - Con_Printf( "clamp " ); + gEngfuncs.Con_Printf( "clamp " ); else if( image->flags & TF_BORDER ) - Con_Printf( "border " ); - else Con_Printf( "repeat " ); - Con_Printf( " %d ", image->depth ); - Con_Printf( " %s\n", image->name ); + gEngfuncs.Con_Printf( "border " ); + else gEngfuncs.Con_Printf( "repeat " ); + gEngfuncs.Con_Printf( " %d ", image->depth ); + gEngfuncs.Con_Printf( " %s\n", image->name ); } - Con_Printf( "---------------------------------------------------------\n" ); - Con_Printf( "%i total textures\n", texCount ); - Con_Printf( "%s total memory used\n", Q_memprint( bytes )); - Con_Printf( "\n" ); + gEngfuncs.Con_Printf( "---------------------------------------------------------\n" ); + gEngfuncs.Con_Printf( "%i total textures\n", texCount ); + gEngfuncs.Con_Printf( "%s total memory used\n", Q_memprint( bytes )); + gEngfuncs.Con_Printf( "\n" ); } /* @@ -2188,7 +2172,7 @@ void R_InitImages( void ) // create unused 0-entry Q_strncpy( gl_textures->name, "*unused*", sizeof( gl_textures->name )); - gl_textures->hashValue = COM_HashKey( gl_textures->name, TEXTURES_HASH_SIZE ); + gl_textures->hashValue = gEngfuncs.COM_HashKey( gl_textures->name, TEXTURES_HASH_SIZE ); gl_textures->nextHash = gl_texturesHashTable[gl_textures->hashValue]; gl_texturesHashTable[gl_textures->hashValue] = gl_textures; gl_numTextures = 1; @@ -2197,7 +2181,7 @@ void R_InitImages( void ) R_SetTextureParameters(); GL_CreateInternalTextures(); - Cmd_AddCommand( "texturelist", R_TextureList_f, "display loaded textures list" ); + gEngfuncs.Cmd_AddCommand( "texturelist", R_TextureList_f, "display loaded textures list" ); } /* @@ -2210,7 +2194,7 @@ void R_ShutdownImages( void ) gl_texture_t *tex; int i; - Cmd_RemoveCommand( "texturelist" ); + gEngfuncs.Cmd_RemoveCommand( "texturelist" ); GL_CleanupAllTextureUnits(); for( i = 0, tex = gl_textures; i < gl_numTextures; i++, tex++ ) diff --git a/engine/client/gl_local.h b/ref_gl/gl_local.h similarity index 71% rename from engine/client/gl_local.h rename to ref_gl/gl_local.h index b938295f..0d7174b5 100644 --- a/engine/client/gl_local.h +++ b/ref_gl/gl_local.h @@ -15,13 +15,45 @@ 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" #include "protocol.h" #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" +//#include "cvar.h" + +#ifndef offsetof +#define offsetof(s,m) (size_t)&(((s *)0)->m) +#endif // offsetof + +#define ASSERT(x) if(!( x )) gEngfuncs.Host_Error( "assert failed at %s:%i\n", __FILE__, __LINE__ ) +#define Assert(x) if(!( x )) gEngfuncs.Host_Error( "assert failed at %s:%i\n", __FILE__, __LINE__ ) + +#include + +#define CVAR_DEFINE( cv, cvname, cvstr, cvflags, cvdesc ) cvar_t cv = { cvname, cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, cvdesc } +#define CVAR_DEFINE_AUTO( cv, cvstr, cvflags, cvdesc ) cvar_t cv = { #cv, cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, cvdesc } +#define CVAR_TO_BOOL( x ) ((x) && ((x)->value != 0.0f) ? true : false ) + +#define WORLD (gEngfuncs.GetWorld()) +#define WORLDMODEL (gEngfuncs.pfnGetModelByIndex( 1 )) +#define MOVEVARS (gEngfuncs.pfnGetMoveVars()) + +// make mod_ref.h? +#define LM_SAMPLE_SIZE 16 + extern byte *r_temppool; @@ -49,13 +81,10 @@ extern byte *r_temppool; #define RP_NONVIEWERREF (RP_ENVVIEW) #define R_ModelOpaque( rm ) ( rm == kRenderNormal ) #define R_StaticEntity( ent ) ( VectorIsNull( ent->origin ) && VectorIsNull( ent->angles )) -#define RP_LOCALCLIENT( e ) ((e) != NULL && (e)->index == ( cl.playernum + 1 ) && e->player ) +#define RP_LOCALCLIENT( e ) ((e) != NULL && (e)->index == ENGINE_GET_PARM( PARM_PLAYER_INDEX ) && e->player ) #define RP_NORMALPASS() ( FBitSet( RI.params, RP_NONVIEWERREF ) == 0 ) -#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 CL_IsViewEntityLocalPlayer() ( ENGINE_GET_PARM( PARM_VIEWENT_INDEX ) == ENGINE_GET_PARM( PARM_PLAYER_INDEX ) ) #define CULL_VISIBLE 0 // not culled #define CULL_BACKSIDE 1 // backside of transparent wall @@ -215,7 +244,9 @@ typedef struct // cull info vec3_t modelorg; // relative to viewpoint -} ref_globals_t; + + qboolean fCustomSkybox; +} gl_globals_t; typedef struct { @@ -239,18 +270,12 @@ typedef struct extern ref_speeds_t r_stats; extern ref_instance_t RI; -extern ref_globals_t tr; +extern gl_globals_t tr; extern float gldepthmin, gldepthmax; -extern dlight_t cl_dlights[MAX_DLIGHTS]; -extern dlight_t cl_elights[MAX_ELIGHTS]; #define r_numEntities (tr.draw_list->num_solid_entities + tr.draw_list->num_trans_entities) #define r_numStatics (r_stats.c_client_ents) -extern struct beam_s *cl_active_beams; -extern struct beam_s *cl_free_beams; -extern struct particle_s *cl_free_particles; - // // gl_backend.c // @@ -273,6 +298,13 @@ void GL_TextureTarget( uint target ); void GL_Cull( GLenum cull ); void R_ShowTextures( void ); void R_ShowTree( void ); +void SCR_TimeRefresh_f( void ); + +// +// gl_beams.c +// +void CL_DrawBeams( int fTrans, BEAM *active_beams ); +qboolean R_BeamCull( const vec3_t start, const vec3_t end, qboolean pvsOnly ); // // gl_cull.c @@ -296,7 +328,7 @@ void R_ClearDecals( void ); // gl_draw.c // void R_Set2DMode( qboolean enable ); -void R_DrawTileClear( int x, int y, int w, int h ); +void R_DrawTileClear( int texnum, int x, int y, int w, int h ); void R_UploadStretchRaw( int texture, int cols, int rows, int width, int height, const byte *data ); // @@ -323,21 +355,16 @@ void GL_UpdateTexSize( int texnum, int width, int height, int depth ); void GL_ApplyTextureParams( gl_texture_t *tex ); int GL_FindTexture( const char *name ); void GL_FreeTexture( GLenum texnum ); -void GL_FreeImage( const char *name ); const char *GL_Target( GLenum target ); void R_InitDlightTexture( void ); void R_TextureList_f( void ); void R_InitImages( void ); void R_ShutdownImages( void ); -// -// gl_refrag.c -// -void R_StoreEfrags( efrag_t **ppefrag, int framecount ); - // // gl_rlight.c // +void CL_RunLightStyles( void ); void R_PushDlights( void ); void R_AnimateLight( void ); void R_GetLightSpot( vec3_t lightspot ); @@ -358,8 +385,7 @@ void R_SetupRefParams( const struct ref_viewpass_s *rvp ); void R_TranslateForEntity( cl_entity_t *e ); void R_RotateForEntity( cl_entity_t *e ); void R_SetupGL( qboolean set_gl_state ); -qboolean R_InitRenderAPI( void ); -void R_AllowFog( int allowed ); +void R_AllowFog( qboolean allowed ); void R_SetupFrustum( void ); void R_FindViewLeaf( void ); void R_PushScene( void ); @@ -369,8 +395,6 @@ void R_DrawFog( void ); // // gl_rmath.c // -float V_CalcFov( float *fov_x, float width, float height ); -void V_AdjustFov( float *fov_x, float *fov_y, float width, float height, qboolean lock_x ); void Matrix4x4_ToArrayFloatGL( const matrix4x4 in, float out[16] ); void Matrix4x4_FromArrayFloatGL( matrix4x4 out, const float in[16] ); void Matrix4x4_Concat( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 ); @@ -387,7 +411,7 @@ void Matrix4x4_CreateOrtho(matrix4x4 m, float xLeft, float xRight, float yBottom void Matrix4x4_CreateModelview( matrix4x4 out ); // -// gl_rmisc. +// gl_rmisc.c // void R_ClearStaticEntities( void ); @@ -412,6 +436,14 @@ void R_GenerateVBO(); void R_ClearVBO(); void R_AddDecalVBO( decal_t *pdecal, msurface_t *surf ); +// +// gl_rpart.c +// +void CL_DrawParticlesExternal( const ref_viewpass_t *rvp, qboolean trans_pass, float frametime ); +void CL_DrawParticles( double frametime, particle_t *cl_active_particles, float partsize ); +void CL_DrawTracers( double frametime, particle_t *cl_active_tracers ); + + // // gl_sprite.c // @@ -433,6 +465,12 @@ int R_GetEntityRenderMode( cl_entity_t *ent ); void R_DrawStudioModel( cl_entity_t *e ); player_info_t *pfnPlayerInfo( int index ); void R_GatherPlayerLight( void ); +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 R_StudioResetPlayerModels( void ); +void CL_InitStudioAPI( void ); +void Mod_StudioLoadTextures( model_t *mod, void *data ); +void Mod_StudioUnloadTextures( void *data ); // // gl_alias.c @@ -452,20 +490,41 @@ void R_DrawSkyBox( void ); void R_DrawClouds( void ); void EmitWaterPolys( msurface_t *warp, qboolean reverse ); -#include "vid_common.h" +// +// gl_vgui.c +// +void VGUI_DrawInit( void ); +void VGUI_DrawShutdown( void ); +void VGUI_SetupDrawingText( int *pColor ); +void VGUI_SetupDrawingRect( int *pColor ); +void VGUI_SetupDrawingImage( int *pColor ); +void VGUI_BindTexture( int id ); +void VGUI_EnableTexture( qboolean enable ); +void VGUI_CreateTexture( int id, int width, int height ); +void VGUI_UploadTexture( int id, const char *buffer, int width, int height ); +void VGUI_UploadTextureBlock( int id, int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight ); +void VGUI_DrawQuad( const vpoint_t *ul, const vpoint_t *lr ); +void VGUI_GetTextureSizes( int *width, int *height ); +int VGUI_GenerateTexture( void ); + +//#include "vid_common.h" // // renderer exports // qboolean R_Init( void ); void R_Shutdown( void ); +void GL_SetupAttributes( int safegl ); +void GL_OnContextCreated( void ); +void GL_InitExtensions( void ); +void GL_ClearExtensions( void ); void VID_CheckChanges( void ); int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags ); void GL_FreeImage( const char *name ); qboolean VID_ScreenShot( const char *filename, int shot_type ); qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qboolean skyshot ); void R_BeginFrame( qboolean clearScene ); -void R_RenderFrame( const struct ref_viewpass_s *vp ); +int R_RenderFrame( const struct ref_viewpass_s *vp ); void R_EndFrame( void ); void R_ClearScene( void ); void R_GetTextureParms( int *w, int *h, int texnum ); @@ -479,10 +538,9 @@ int R_WorldToScreen( const vec3_t point, vec3_t screen ); void R_ScreenToWorld( const vec3_t screen, vec3_t point ); qboolean R_AddEntity( struct cl_entity_s *pRefEntity, int entityType ); void Mod_LoadMapSprite( struct model_s *mod, const void *buffer, size_t size, qboolean *loaded ); -void Mod_UnloadSpriteModel( struct model_s *mod ); -void Mod_UnloadStudioModel( struct model_s *mod ); -void Mod_UnloadBrushModel( struct model_s *mod ); +void Mod_SpriteUnloadTextures( void *data ); void Mod_UnloadAliasModel( struct model_s *mod ); +void Mod_AliasUnloadTextures( void *data ); void GL_SetRenderMode( int mode ); void R_RunViewmodelEvents( void ); void R_DrawViewModel( void ); @@ -491,9 +549,43 @@ void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos void R_RemoveEfrags( struct cl_entity_s *ent ); void R_AddEfrags( struct cl_entity_s *ent ); void R_DecalRemoveAll( int texture ); +int R_CreateDecalList( decallist_t *pList ); +void R_ClearAllDecals( void ); byte *Mod_GetCurrentVis( void ); -void Mod_SetOrthoBounds( float *mins, float *maxs ); +void Mod_SetOrthoBounds( const float *mins, const float *maxs ); void R_NewMap( void ); +void CL_AddCustomBeam( cl_entity_t *pEnvBeam ); + +// +// gl_opengl.c +// +#define GL_CheckForErrors() GL_CheckForErrors_( __FILE__, __LINE__ ) +void GL_CheckForErrors_( const char *filename, const int fileline ); +const char *GL_ErrorString( int err ); +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 ); + +// +// gl_triapi.c +// +void TriRenderMode( int mode ); +void TriBegin( int mode ); +void TriEnd( void ); +void TriTexCoord2f( float u, float v ); +void TriVertex3fv( const float *v ); +void TriVertex3f( float x, float y, float z ); +void _TriColor4f( float r, float g, float b, float a ); +void TriColor4f( float r, float g, float b, float a ); +void TriColor4ub( byte r, byte g, byte b, byte a ); +void TriBrightness( float brightness ); +int TriWorldToScreen( const float *world, float *screen ); +int TriSpriteTexture( model_t *pSpriteModel, int frame ); +void TriFog( float flFogColor[3], float flStart, float flEnd, int bOn ); +void TriGetMatrix( const int pname, float *matrix ); +void TriFogParams( float flDensity, int iFogSkybox ); +void TriCullFace( TRICULLSTYLE mode ); /* ======================================================================= @@ -530,17 +622,6 @@ enum GL_EXTCOUNT, // must be last }; -enum -{ - GL_KEEP_UNIT = -1, - XASH_TEXTURE0 = 0, - XASH_TEXTURE1, - XASH_TEXTURE2, - XASH_TEXTURE3, // g-cont. 4 units should be enough - XASH_TEXTURE4, // mittorn. bump+detail needs 5 for single-pass - MAX_TEXTURE_UNITS = 32 // can't access to all over units without GLSL or cg -}; - typedef enum { GLHW_GENERIC, // where everthing works the way it should @@ -594,10 +675,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]; @@ -611,17 +690,6 @@ 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 { @@ -638,61 +706,82 @@ typedef struct extern glconfig_t glConfig; extern glstate_t glState; +// move to engine extern glwstate_t glw_state; +extern ref_api_t gEngfuncs; +extern ref_globals_t *gpGlobals; + +#define ENGINE_GET_PARM_ (*gEngfuncs.EngineGetParm) +#define ENGINE_GET_PARM( parm ) ENGINE_GET_PARM_( ( parm ), 0 ) // // renderer cvars // -extern convar_t *gl_texture_anisotropy; -extern convar_t *gl_extensions; -extern convar_t *gl_check_errors; -extern convar_t *gl_texture_lodbias; -extern convar_t *gl_texture_nearest; -extern convar_t *gl_wgl_msaa_samples; -extern convar_t *gl_lightmap_nearest; -extern convar_t *gl_keeptjunctions; -extern convar_t *gl_emboss_scale; -extern convar_t *gl_round_down; -extern convar_t *gl_detailscale; -extern convar_t *gl_wireframe; -extern convar_t *gl_polyoffset; -extern convar_t *gl_finish; -extern convar_t *gl_nosort; -extern convar_t *gl_clear; -extern convar_t *gl_test; // cvar to testify new effects -extern convar_t *gl_msaa; -extern convar_t *gl_stencilbits; +extern cvar_t *gl_texture_anisotropy; +extern cvar_t *gl_extensions; +extern cvar_t *gl_check_errors; +extern cvar_t *gl_texture_lodbias; +extern cvar_t *gl_texture_nearest; +extern cvar_t *gl_lightmap_nearest; +extern cvar_t *gl_keeptjunctions; +extern cvar_t *gl_emboss_scale; +extern cvar_t *gl_round_down; +extern cvar_t *gl_detailscale; +extern cvar_t *gl_wireframe; +extern cvar_t *gl_polyoffset; +extern cvar_t *gl_finish; +extern cvar_t *gl_nosort; +extern cvar_t *gl_clear; +extern cvar_t *gl_test; // cvar to testify new effects +extern cvar_t *gl_msaa; +extern cvar_t *gl_stencilbits; -extern convar_t *r_speeds; -extern convar_t *r_fullbright; -extern convar_t *r_norefresh; -extern convar_t *r_showtree; // build graph of visible hull -extern convar_t *r_lighting_extended; -extern convar_t *r_lighting_modulate; -extern convar_t *r_lighting_ambient; -extern convar_t *r_studio_lambert; -extern convar_t *r_detailtextures; -extern convar_t *r_drawentities; -extern convar_t *r_adjust_fov; -extern convar_t *r_decals; -extern convar_t *r_novis; -extern convar_t *r_nocull; -extern convar_t *r_lockpvs; -extern convar_t *r_lockfrustum; -extern convar_t *r_traceglow; -extern convar_t *r_dynamic; -extern convar_t *r_lightmap; -extern convar_t *r_vbo; -extern convar_t *r_vbo_dlightmode; +extern cvar_t *r_speeds; +extern cvar_t *r_fullbright; +extern cvar_t *r_norefresh; +extern cvar_t *r_showtree; // build graph of visible hull +extern cvar_t *r_lighting_extended; +extern cvar_t *r_lighting_modulate; +extern cvar_t *r_lighting_ambient; +extern cvar_t *r_studio_lambert; +extern cvar_t *r_detailtextures; +extern cvar_t *r_drawentities; +extern cvar_t *r_decals; +extern cvar_t *r_novis; +extern cvar_t *r_nocull; +extern cvar_t *r_lockpvs; +extern cvar_t *r_lockfrustum; +extern cvar_t *r_traceglow; +extern cvar_t *r_dynamic; +extern cvar_t *r_lightmap; +extern cvar_t *r_vbo; +extern cvar_t *r_vbo_dlightmode; -extern convar_t *vid_displayfrequency; -extern convar_t *vid_fullscreen; -extern convar_t *vid_brightness; -extern convar_t *vid_gamma; -extern convar_t *vid_highdpi; +extern cvar_t *vid_brightness; +extern cvar_t *vid_gamma; -extern convar_t *window_xpos; -extern convar_t *window_ypos; -extern convar_t *scr_height; +// +// engine shared convars +// +extern cvar_t *gl_showtextures; +extern cvar_t *tracerred; +extern cvar_t *tracergreen; +extern cvar_t *tracerblue; +extern cvar_t *traceralpha; +extern cvar_t *cl_lightstyle_lerping; +extern cvar_t *r_showhull; -#endif//GL_LOCAL_H +// +// engine callbacks +// +#include "crtlib.h" + +#define Mem_Malloc( pool, size ) gEngfuncs._Mem_Alloc( pool, size, false, __FILE__, __LINE__ ) +#define Mem_Calloc( pool, size ) gEngfuncs._Mem_Alloc( pool, size, true, __FILE__, __LINE__ ) +#define Mem_Realloc( pool, ptr, size ) gEngfuncs._Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ ) +#define Mem_Free( mem ) gEngfuncs._Mem_Free( mem, __FILE__, __LINE__ ) +#define Mem_AllocPool( name ) gEngfuncs._Mem_AllocPool( name, __FILE__, __LINE__ ) +#define Mem_FreePool( pool ) gEngfuncs._Mem_FreePool( pool, __FILE__, __LINE__ ) +#define Mem_EmptyPool( pool ) gEngfuncs._Mem_EmptyPool( pool, __FILE__, __LINE__ ) + +#endif // GL_LOCAL_H diff --git a/ref_gl/gl_opengl.c b/ref_gl/gl_opengl.c new file mode 100644 index 00000000..ac1a6b01 --- /dev/null +++ b/ref_gl/gl_opengl.c @@ -0,0 +1,1128 @@ + +#include "gl_local.h" + +cvar_t *gl_extensions; +cvar_t *gl_texture_anisotropy; +cvar_t *gl_texture_lodbias; +cvar_t *gl_texture_nearest; +cvar_t *gl_lightmap_nearest; +cvar_t *gl_keeptjunctions; +cvar_t *gl_emboss_scale; +cvar_t *gl_detailscale; +cvar_t *gl_check_errors; +cvar_t *gl_polyoffset; +cvar_t *gl_wireframe; +cvar_t *gl_finish; +cvar_t *gl_nosort; +cvar_t *gl_vsync; +cvar_t *gl_clear; +cvar_t *gl_test; +cvar_t *gl_msaa; +cvar_t *gl_stencilbits; +cvar_t *r_speeds; +cvar_t *r_fullbright; +cvar_t *r_norefresh; +cvar_t *r_showtree; +cvar_t *r_lighting_extended; +cvar_t *r_lighting_modulate; +cvar_t *r_lighting_ambient; +cvar_t *r_detailtextures; +cvar_t *r_drawentities; +cvar_t *r_adjust_fov; +cvar_t *r_decals; +cvar_t *r_novis; +cvar_t *r_nocull; +cvar_t *r_lockpvs; +cvar_t *r_lockfrustum; +cvar_t *r_traceglow; +cvar_t *r_dynamic; +cvar_t *r_lightmap; +cvar_t *r_showhull; +cvar_t *gl_round_down; +cvar_t *r_vbo; +cvar_t *r_vbo_dlightmode; +cvar_t *gl_showtextures; +cvar_t *cl_lightstyle_lerping; + +cvar_t *vid_brightness; +cvar_t *vid_gamma; +cvar_t *tracerred; +cvar_t *tracergreen; +cvar_t *tracerblue; +cvar_t *traceralpha; + +byte *r_temppool; + +gl_globals_t tr; +glconfig_t glConfig; +glstate_t glState; +glwstate_t glw_state; + +#define GL_CALL( x ) #x, (void**)&p##x +static dllfunc_t opengl_110funcs[] = +{ + { GL_CALL( glClearColor ) }, + { GL_CALL( glClear ) }, + { GL_CALL( glAlphaFunc ) }, + { GL_CALL( glBlendFunc ) }, + { GL_CALL( glCullFace ) }, + { GL_CALL( glDrawBuffer ) }, + { GL_CALL( glReadBuffer ) }, + { GL_CALL( glAccum ) }, + { GL_CALL( glEnable ) }, + { GL_CALL( glDisable ) }, + { GL_CALL( glEnableClientState ) }, + { GL_CALL( glDisableClientState ) }, + { GL_CALL( glGetBooleanv ) }, + { GL_CALL( glGetDoublev ) }, + { GL_CALL( glGetFloatv ) }, + { GL_CALL( glGetIntegerv ) }, + { GL_CALL( glGetError ) }, + { GL_CALL( glGetString ) }, + { GL_CALL( glFinish ) }, + { GL_CALL( glFlush ) }, + { GL_CALL( glClearDepth ) }, + { GL_CALL( glDepthFunc ) }, + { GL_CALL( glDepthMask ) }, + { GL_CALL( glDepthRange ) }, + { GL_CALL( glFrontFace ) }, + { GL_CALL( glDrawElements ) }, + { GL_CALL( glDrawArrays ) }, + { GL_CALL( glColorMask ) }, + { GL_CALL( glIndexPointer ) }, + { GL_CALL( glVertexPointer ) }, + { GL_CALL( glNormalPointer ) }, + { GL_CALL( glColorPointer ) }, + { GL_CALL( glTexCoordPointer ) }, + { GL_CALL( glArrayElement ) }, + { GL_CALL( glColor3f ) }, + { GL_CALL( glColor3fv ) }, + { GL_CALL( glColor4f ) }, + { GL_CALL( glColor4fv ) }, + { GL_CALL( glColor3ub ) }, + { GL_CALL( glColor4ub ) }, + { GL_CALL( glColor4ubv ) }, + { GL_CALL( glTexCoord1f ) }, + { GL_CALL( glTexCoord2f ) }, + { GL_CALL( glTexCoord3f ) }, + { GL_CALL( glTexCoord4f ) }, + { GL_CALL( glTexCoord1fv ) }, + { GL_CALL( glTexCoord2fv ) }, + { GL_CALL( glTexCoord3fv ) }, + { GL_CALL( glTexCoord4fv ) }, + { GL_CALL( glTexGenf ) }, + { GL_CALL( glTexGenfv ) }, + { GL_CALL( glTexGeni ) }, + { GL_CALL( glVertex2f ) }, + { GL_CALL( glVertex3f ) }, + { GL_CALL( glVertex3fv ) }, + { GL_CALL( glNormal3f ) }, + { GL_CALL( glNormal3fv ) }, + { GL_CALL( glBegin ) }, + { GL_CALL( glEnd ) }, + { GL_CALL( glLineWidth ) }, + { GL_CALL( glPointSize ) }, + { GL_CALL( glMatrixMode ) }, + { GL_CALL( glOrtho ) }, + { GL_CALL( glRasterPos2f ) }, + { GL_CALL( glFrustum ) }, + { GL_CALL( glViewport ) }, + { GL_CALL( glPushMatrix ) }, + { GL_CALL( glPopMatrix ) }, + { GL_CALL( glPushAttrib ) }, + { GL_CALL( glPopAttrib ) }, + { GL_CALL( glLoadIdentity ) }, + { GL_CALL( glLoadMatrixd ) }, + { GL_CALL( glLoadMatrixf ) }, + { GL_CALL( glMultMatrixd ) }, + { GL_CALL( glMultMatrixf ) }, + { GL_CALL( glRotated ) }, + { GL_CALL( glRotatef ) }, + { GL_CALL( glScaled ) }, + { GL_CALL( glScalef ) }, + { GL_CALL( glTranslated ) }, + { GL_CALL( glTranslatef ) }, + { GL_CALL( glReadPixels ) }, + { GL_CALL( glDrawPixels ) }, + { GL_CALL( glStencilFunc ) }, + { GL_CALL( glStencilMask ) }, + { GL_CALL( glStencilOp ) }, + { GL_CALL( glClearStencil ) }, + { GL_CALL( glIsEnabled ) }, + { GL_CALL( glIsList ) }, + { GL_CALL( glIsTexture ) }, + { GL_CALL( glTexEnvf ) }, + { GL_CALL( glTexEnvfv ) }, + { GL_CALL( glTexEnvi ) }, + { GL_CALL( glTexParameterf ) }, + { GL_CALL( glTexParameterfv ) }, + { GL_CALL( glTexParameteri ) }, + { GL_CALL( glHint ) }, + { GL_CALL( glPixelStoref ) }, + { GL_CALL( glPixelStorei ) }, + { GL_CALL( glGenTextures ) }, + { GL_CALL( glDeleteTextures ) }, + { GL_CALL( glBindTexture ) }, + { GL_CALL( glTexImage1D ) }, + { GL_CALL( glTexImage2D ) }, + { GL_CALL( glTexSubImage1D ) }, + { GL_CALL( glTexSubImage2D ) }, + { GL_CALL( glCopyTexImage1D ) }, + { GL_CALL( glCopyTexImage2D ) }, + { GL_CALL( glCopyTexSubImage1D ) }, + { GL_CALL( glCopyTexSubImage2D ) }, + { GL_CALL( glScissor ) }, + { GL_CALL( glGetTexImage ) }, + { GL_CALL( glGetTexEnviv ) }, + { GL_CALL( glPolygonOffset ) }, + { GL_CALL( glPolygonMode ) }, + { GL_CALL( glPolygonStipple ) }, + { GL_CALL( glClipPlane ) }, + { GL_CALL( glGetClipPlane ) }, + { GL_CALL( glShadeModel ) }, + { GL_CALL( glGetTexLevelParameteriv ) }, + { GL_CALL( glGetTexLevelParameterfv ) }, + { GL_CALL( glFogfv ) }, + { GL_CALL( glFogf ) }, + { GL_CALL( glFogi ) }, + { NULL , NULL } +}; + +static dllfunc_t debugoutputfuncs[] = +{ + { GL_CALL( glDebugMessageControlARB ) }, + { GL_CALL( glDebugMessageInsertARB ) }, + { GL_CALL( glDebugMessageCallbackARB ) }, + { GL_CALL( glGetDebugMessageLogARB ) }, + { NULL , NULL } +}; + +static dllfunc_t multitexturefuncs[] = +{ + { GL_CALL( glMultiTexCoord1f ) }, + { GL_CALL( glMultiTexCoord2f ) }, + { GL_CALL( glMultiTexCoord3f ) }, + { GL_CALL( glMultiTexCoord4f ) }, + { GL_CALL( glActiveTexture ) }, + { GL_CALL( glActiveTextureARB ) }, + { GL_CALL( glClientActiveTexture ) }, + { GL_CALL( glClientActiveTextureARB ) }, + { NULL , NULL } +}; + +static dllfunc_t texture3dextfuncs[] = +{ + { GL_CALL( glTexImage3D ) }, + { GL_CALL( glTexSubImage3D ) }, + { GL_CALL( glCopyTexSubImage3D ) }, + { NULL , NULL } +}; + +static dllfunc_t texturecompressionfuncs[] = +{ + { GL_CALL( glCompressedTexImage3DARB ) }, + { GL_CALL( glCompressedTexImage2DARB ) }, + { GL_CALL( glCompressedTexImage1DARB ) }, + { GL_CALL( glCompressedTexSubImage3DARB ) }, + { GL_CALL( glCompressedTexSubImage2DARB ) }, + { GL_CALL( glCompressedTexSubImage1DARB ) }, + { GL_CALL( glGetCompressedTexImage ) }, + { NULL , NULL } +}; + +static dllfunc_t vbofuncs[] = +{ + { GL_CALL( glBindBufferARB ) }, + { GL_CALL( glDeleteBuffersARB ) }, + { GL_CALL( glGenBuffersARB ) }, + { GL_CALL( glIsBufferARB ) }, + { GL_CALL( glMapBufferARB ) }, + { GL_CALL( glUnmapBufferARB ) }, // , + { GL_CALL( glBufferDataARB ) }, + { GL_CALL( glBufferSubDataARB ) }, + { NULL, NULL} +}; + +/* +======================== +DebugCallback + +For ARB_debug_output +======================== +*/ +static void APIENTRY GL_DebugOutput( GLuint source, GLuint type, GLuint id, GLuint severity, GLint length, const GLcharARB *message, GLvoid *userParam ) +{ + switch( type ) + { + case GL_DEBUG_TYPE_ERROR_ARB: + gEngfuncs.Con_Printf( S_OPENGL_ERROR "%s\n", message ); + break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: + gEngfuncs.Con_Printf( S_OPENGL_WARN "%s\n", message ); + break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: + gEngfuncs.Con_Printf( S_OPENGL_WARN "%s\n", message ); + break; + case GL_DEBUG_TYPE_PORTABILITY_ARB: + gEngfuncs.Con_Reportf( S_OPENGL_WARN "%s\n", message ); + break; + case GL_DEBUG_TYPE_PERFORMANCE_ARB: + gEngfuncs.Con_Printf( S_OPENGL_NOTE "%s\n", message ); + break; + case GL_DEBUG_TYPE_OTHER_ARB: + default: + gEngfuncs.Con_Printf( S_OPENGL_NOTE "%s\n", message ); + break; + } +} + +/* +================= +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 gEngfuncs.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; + gEngfuncs.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; + cvar_t *parm = NULL; + const char *extensions_string; + + gEngfuncs.Con_Reportf( "GL_CheckExtension: %s ", name ); + GL_SetExtension( r_ext, true ); + + if( cvarname ) + { + // system config disable extensions + parm = gEngfuncs.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 )) + { + gEngfuncs.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 + gEngfuncs.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 *)gEngfuncs.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 )) + gEngfuncs.Con_Reportf( "- ^2enabled\n" ); + else gEngfuncs.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( 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 ) +{ + gEngfuncs.Con_Printf( "\n" ); + gEngfuncs.Con_Printf( "GL_VENDOR: %s\n", glConfig.vendor_string ); + gEngfuncs.Con_Printf( "GL_RENDERER: %s\n", glConfig.renderer_string ); + gEngfuncs.Con_Printf( "GL_VERSION: %s\n", glConfig.version_string ); + + // don't spam about extensions + gEngfuncs.Con_Reportf( "GL_EXTENSIONS: %s\n", glConfig.extensions_string ); + + gEngfuncs.Con_Printf( "GL_MAX_TEXTURE_SIZE: %i\n", glConfig.max_2d_texture_size ); + + if( GL_Support( GL_ARB_MULTITEXTURE )) + gEngfuncs.Con_Printf( "GL_MAX_TEXTURE_UNITS_ARB: %i\n", glConfig.max_texture_units ); + if( GL_Support( GL_TEXTURE_CUBEMAP_EXT )) + gEngfuncs.Con_Printf( "GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB: %i\n", glConfig.max_cubemap_size ); + if( GL_Support( GL_ANISOTROPY_EXT )) + gEngfuncs.Con_Printf( "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: %.1f\n", glConfig.max_texture_anisotropy ); + if( GL_Support( GL_TEXTURE_2D_RECT_EXT )) + gEngfuncs.Con_Printf( "GL_MAX_RECTANGLE_TEXTURE_SIZE: %i\n", glConfig.max_2d_rectangle_size ); + if( GL_Support( GL_TEXTURE_ARRAY_EXT )) + gEngfuncs.Con_Printf( "GL_MAX_ARRAY_TEXTURE_LAYERS_EXT: %i\n", glConfig.max_2d_texture_layers ); + if( GL_Support( GL_SHADER_GLSL100_EXT )) + { + gEngfuncs.Con_Printf( "GL_MAX_TEXTURE_COORDS_ARB: %i\n", glConfig.max_texture_coords ); + gEngfuncs.Con_Printf( "GL_MAX_TEXTURE_IMAGE_UNITS_ARB: %i\n", glConfig.max_teximage_units ); + gEngfuncs.Con_Printf( "GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB: %i\n", glConfig.max_vertex_uniforms ); + gEngfuncs.Con_Printf( "GL_MAX_VERTEX_ATTRIBS_ARB: %i\n", glConfig.max_vertex_attribs ); + } + + gEngfuncs.Con_Printf( "\n" ); + gEngfuncs.Con_Printf( "MODE: %ix%i\n", gpGlobals->width, gpGlobals->height ); + gEngfuncs.Con_Printf( "\n" ); + gEngfuncs.Con_Printf( "VERTICAL SYNC: %s\n", gl_vsync->value ? "enabled" : "disabled" ); + gEngfuncs.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 ); +} + +#ifdef XASH_GLES +void GL_InitExtensionsGLES( void ) +{ + // intialize wrapper type +#ifdef XASH_NANOGL + glConfig.context = CONTEXT_TYPE_GLES_1_X; + glConfig.wrapper = GLES_WRAPPER_NANOGL; +#elif defined( XASH_WES ) + glConfig.context = CONTEXT_TYPE_GLES_2_X; + glConfig.wrapper = GLES_WRAPPER_WES; +#endif + + glConfig.hardware_type = GLHW_GENERIC; + + // initalize until base opengl functions loaded + GL_SetExtension( GL_DRAW_RANGEELEMENTS_EXT, true ); + GL_SetExtension( GL_ARB_MULTITEXTURE, true ); + pglGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, &glConfig.max_texture_units ); + glConfig.max_texture_coords = glConfig.max_texture_units = 4; + + GL_SetExtension( GL_ENV_COMBINE_EXT, true ); + GL_SetExtension( GL_DOT3_ARB_EXT, true ); + GL_SetExtension( GL_TEXTURE_3D_EXT, false ); + GL_SetExtension( GL_SGIS_MIPMAPS_EXT, true ); // gles specs + GL_SetExtension( GL_ARB_VERTEX_BUFFER_OBJECT_EXT, true ); // gles specs + + // hardware cubemaps + GL_CheckExtension( "GL_OES_texture_cube_map", NULL, "gl_texture_cubemap", GL_TEXTURECUBEMAP_EXT ); + + if( GL_Support( GL_TEXTURECUBEMAP_EXT )) + pglGetIntegerv( GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, &glConfig.max_cubemap_size ); + + GL_SetExtension( GL_ARB_SEAMLESS_CUBEMAP, false ); + + GL_SetExtension( GL_EXT_POINTPARAMETERS, false ); + GL_CheckExtension( "GL_OES_texture_npot", NULL, "gl_texture_npot", GL_ARB_TEXTURE_NPOT_EXT ); + + GL_SetExtension( GL_TEXTURE_COMPRESSION_EXT, false ); + GL_SetExtension( GL_CUSTOM_VERTEX_ARRAY_EXT, false ); + GL_SetExtension( GL_CLAMPTOEDGE_EXT, true ); // by gles1 specs + GL_SetExtension( GL_ANISOTROPY_EXT, false ); + GL_SetExtension( GL_TEXTURE_LODBIAS, false ); + GL_SetExtension( GL_CLAMP_TEXBORDER_EXT, false ); + GL_SetExtension( GL_BLEND_MINMAX_EXT, false ); + GL_SetExtension( GL_BLEND_SUBTRACT_EXT, false ); + GL_SetExtension( GL_SEPARATESTENCIL_EXT, false ); + GL_SetExtension( GL_STENCILTWOSIDE_EXT, false ); + GL_SetExtension( GL_TEXTURE_ENV_ADD_EXT,false ); + GL_SetExtension( GL_SHADER_OBJECTS_EXT, false ); + GL_SetExtension( GL_SHADER_GLSL100_EXT, false ); + GL_SetExtension( GL_VERTEX_SHADER_EXT,false ); + GL_SetExtension( GL_FRAGMENT_SHADER_EXT, false ); + GL_SetExtension( GL_SHADOW_EXT, false ); + GL_SetExtension( GL_ARB_DEPTH_FLOAT_EXT, false ); + GL_SetExtension( GL_OCCLUSION_QUERIES_EXT,false ); + GL_CheckExtension( "GL_OES_depth_texture", NULL, "gl_depthtexture", GL_DEPTH_TEXTURE ); + + glConfig.texRectangle = glConfig.max_2d_rectangle_size = 0; // no rectangle + + Cvar_FullSet( "gl_allow_mirrors", "0", CVAR_READ_ONLY); // No support for GLES + +} +#else +void GL_InitExtensionsBigGL() +{ + // intialize wrapper type + glConfig.context = CONTEXT_TYPE_GL; + glConfig.wrapper = GLES_WRAPPER_NONE; + + if( Q_stristr( glConfig.renderer_string, "geforce" )) + glConfig.hardware_type = GLHW_NVIDIA; + else if( Q_stristr( glConfig.renderer_string, "quadro fx" )) + glConfig.hardware_type = GLHW_NVIDIA; + else if( Q_stristr(glConfig.renderer_string, "rv770" )) + glConfig.hardware_type = GLHW_RADEON; + else if( Q_stristr(glConfig.renderer_string, "radeon hd" )) + glConfig.hardware_type = GLHW_RADEON; + else if( Q_stristr( glConfig.renderer_string, "eah4850" ) || Q_stristr( glConfig.renderer_string, "eah4870" )) + glConfig.hardware_type = GLHW_RADEON; + else if( Q_stristr( glConfig.renderer_string, "radeon" )) + glConfig.hardware_type = GLHW_RADEON; + else if( Q_stristr( glConfig.renderer_string, "intel" )) + glConfig.hardware_type = GLHW_INTEL; + else glConfig.hardware_type = GLHW_GENERIC; + + // multitexture + glConfig.max_texture_units = glConfig.max_texture_coords = glConfig.max_teximage_units = 1; + GL_CheckExtension( "GL_ARB_multitexture", multitexturefuncs, "gl_arb_multitexture", GL_ARB_MULTITEXTURE ); + + if( GL_Support( GL_ARB_MULTITEXTURE )) + { + pglGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, &glConfig.max_texture_units ); + } + + if( glConfig.max_texture_units == 1 ) + GL_SetExtension( GL_ARB_MULTITEXTURE, false ); + + // 3d texture support + GL_CheckExtension( "GL_EXT_texture3D", texture3dextfuncs, "gl_texture_3d", GL_TEXTURE_3D_EXT ); + + if( GL_Support( GL_TEXTURE_3D_EXT )) + { + pglGetIntegerv( GL_MAX_3D_TEXTURE_SIZE, &glConfig.max_3d_texture_size ); + + if( glConfig.max_3d_texture_size < 32 ) + { + GL_SetExtension( GL_TEXTURE_3D_EXT, false ); + gEngfuncs.Con_Printf( S_ERROR "GL_EXT_texture3D reported bogus GL_MAX_3D_TEXTURE_SIZE, disabled\n" ); + } + } + + // 2d texture array support + GL_CheckExtension( "GL_EXT_texture_array", texture3dextfuncs, "gl_texture_2d_array", GL_TEXTURE_ARRAY_EXT ); + + if( GL_Support( GL_TEXTURE_ARRAY_EXT )) + pglGetIntegerv( GL_MAX_ARRAY_TEXTURE_LAYERS_EXT, &glConfig.max_2d_texture_layers ); + + // cubemaps support + GL_CheckExtension( "GL_ARB_texture_cube_map", NULL, "gl_texture_cubemap", GL_TEXTURE_CUBEMAP_EXT ); + + if( GL_Support( GL_TEXTURE_CUBEMAP_EXT )) + { + pglGetIntegerv( GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, &glConfig.max_cubemap_size ); + + // check for seamless cubemaps too + GL_CheckExtension( "GL_ARB_seamless_cube_map", NULL, "gl_texture_cubemap_seamless", GL_ARB_SEAMLESS_CUBEMAP ); + } + + GL_CheckExtension( "GL_ARB_texture_non_power_of_two", NULL, "gl_texture_npot", GL_ARB_TEXTURE_NPOT_EXT ); + GL_CheckExtension( "GL_ARB_texture_compression", texturecompressionfuncs, "gl_dds_hardware_support", GL_TEXTURE_COMPRESSION_EXT ); + GL_CheckExtension( "GL_EXT_texture_edge_clamp", NULL, "gl_clamp_to_edge", GL_CLAMPTOEDGE_EXT ); + if( !GL_Support( GL_CLAMPTOEDGE_EXT )) + GL_CheckExtension( "GL_SGIS_texture_edge_clamp", NULL, "gl_clamp_to_edge", GL_CLAMPTOEDGE_EXT ); + + glConfig.max_texture_anisotropy = 0.0f; + GL_CheckExtension( "GL_EXT_texture_filter_anisotropic", NULL, "gl_ext_anisotropic_filter", GL_ANISOTROPY_EXT ); + if( GL_Support( GL_ANISOTROPY_EXT )) + pglGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.max_texture_anisotropy ); + +#ifdef _WIN32 // Win32 only drivers? + // g-cont. because lodbias it too glitchy on Intel's cards + if( glConfig.hardware_type != GLHW_INTEL ) +#endif + GL_CheckExtension( "GL_EXT_texture_lod_bias", NULL, "gl_texture_mipmap_biasing", GL_TEXTURE_LOD_BIAS ); + + if( GL_Support( GL_TEXTURE_LOD_BIAS )) + pglGetFloatv( GL_MAX_TEXTURE_LOD_BIAS_EXT, &glConfig.max_texture_lod_bias ); + + GL_CheckExtension( "GL_ARB_texture_border_clamp", NULL, "gl_ext_texborder_clamp", GL_CLAMP_TEXBORDER_EXT ); + GL_CheckExtension( "GL_ARB_depth_texture", NULL, "gl_depthtexture", GL_DEPTH_TEXTURE ); + GL_CheckExtension( "GL_ARB_texture_float", NULL, "gl_arb_texture_float", GL_ARB_TEXTURE_FLOAT_EXT ); + GL_CheckExtension( "GL_ARB_depth_buffer_float", NULL, "gl_arb_depth_float", GL_ARB_DEPTH_FLOAT_EXT ); + GL_CheckExtension( "GL_EXT_gpu_shader4", NULL, NULL, GL_EXT_GPU_SHADER4 ); // don't confuse users + GL_CheckExtension( "GL_ARB_shading_language_100", NULL, "gl_glslprogram", GL_SHADER_GLSL100_EXT ); + GL_CheckExtension( "GL_ARB_vertex_buffer_object", vbofuncs, "gl_vertex_buffer_object", GL_ARB_VERTEX_BUFFER_OBJECT_EXT ); + + // rectangle textures support + GL_CheckExtension( "GL_ARB_texture_rectangle", NULL, "gl_texture_rectangle", GL_TEXTURE_2D_RECT_EXT ); + + // this won't work without extended context + if( glw_state.extended ) + GL_CheckExtension( "GL_ARB_debug_output", debugoutputfuncs, "gl_debug_output", GL_DEBUG_OUTPUT ); + + if( GL_Support( GL_SHADER_GLSL100_EXT )) + { + pglGetIntegerv( GL_MAX_TEXTURE_COORDS_ARB, &glConfig.max_texture_coords ); + pglGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &glConfig.max_teximage_units ); + + // check for hardware skinning + pglGetIntegerv( GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &glConfig.max_vertex_uniforms ); + pglGetIntegerv( GL_MAX_VERTEX_ATTRIBS_ARB, &glConfig.max_vertex_attribs ); + +#ifdef _WIN32 // Win32 only drivers? + if( glConfig.hardware_type == GLHW_RADEON && glConfig.max_vertex_uniforms > 512 ) + glConfig.max_vertex_uniforms /= 4; // radeon returns not correct info +#endif + } + else + { + // just get from multitexturing + glConfig.max_texture_coords = glConfig.max_teximage_units = glConfig.max_texture_units; + } + + pglGetIntegerv( GL_MAX_TEXTURE_SIZE, &glConfig.max_2d_texture_size ); + if( glConfig.max_2d_texture_size <= 0 ) glConfig.max_2d_texture_size = 256; + + if( GL_Support( GL_TEXTURE_2D_RECT_EXT )) + pglGetIntegerv( GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT, &glConfig.max_2d_rectangle_size ); + +#ifndef XASH_GL_STATIC + // enable gldebug if allowed + if( GL_Support( GL_DEBUG_OUTPUT )) + { + if( gpGlobals->developer ) + { + gEngfuncs.Con_Reportf( "Installing GL_DebugOutput...\n"); + pglDebugMessageCallbackARB( GL_DebugOutput, NULL ); + + // force everything to happen in the main thread instead of in a separate driver thread + pglEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB ); + } + + // enable all the low priority messages + pglDebugMessageControlARB( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, true ); + } +#endif +} +#endif + +void GL_InitExtensions( void ) +{ + // initialize gl extensions + GL_CheckExtension( "OpenGL 1.1.0", opengl_110funcs, NULL, GL_OPENGL_110 ); + + // get our various GL strings + glConfig.vendor_string = pglGetString( GL_VENDOR ); + glConfig.renderer_string = pglGetString( GL_RENDERER ); + glConfig.version_string = pglGetString( GL_VERSION ); + glConfig.extensions_string = pglGetString( GL_EXTENSIONS ); + gEngfuncs.Con_Reportf( "^3Video^7: %s\n", glConfig.renderer_string ); + +#ifdef XASH_GLES + GL_InitExtensionsGLES(); +#else + GL_InitExtensionsBigGL(); +#endif + + if( GL_Support( GL_TEXTURE_2D_RECT_EXT )) + pglGetIntegerv( GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT, &glConfig.max_2d_rectangle_size ); + + gEngfuncs.Cvar_Get( "gl_max_size", va( "%i", glConfig.max_2d_texture_size ), 0, "opengl texture max dims" ); + gEngfuncs.Cvar_Set( "gl_anisotropy", va( "%f", bound( 0, gl_texture_anisotropy->value, glConfig.max_texture_anisotropy ))); + + if( GL_Support( GL_TEXTURE_COMPRESSION_EXT )) + gEngfuncs.Image_AddCmdFlags( IL_DDS_HARDWARE ); + + // MCD has buffering issues +#ifdef _WIN32 + if( Q_strstr( glConfig.renderer_string, "gdi" )) + gEngfuncs.Cvar_SetValue( "gl_finish", 1 ); +#endif + + tr.framecount = tr.visframecount = 1; + glw_state.initialized = true; +} + +void GL_ClearExtensions( void ) +{ + // now all extensions are disabled + memset( glConfig.extension, 0, sizeof( glConfig.extension )); + glw_state.initialized = false; +} + +//======================================================================= + +/* +================= +GL_InitCommands +================= +*/ +void GL_InitCommands( void ) +{ + r_speeds = gEngfuncs.Cvar_Get( "r_speeds", "0", FCVAR_ARCHIVE, "shows renderer speeds" ); + r_fullbright = gEngfuncs.Cvar_Get( "r_fullbright", "0", FCVAR_CHEAT, "disable lightmaps, get fullbright for entities" ); + r_norefresh = gEngfuncs.Cvar_Get( "r_norefresh", "0", 0, "disable 3D rendering (use with caution)" ); + r_showtree = gEngfuncs.Cvar_Get( "r_showtree", "0", FCVAR_ARCHIVE, "build the graph of visible BSP tree" ); + r_lighting_extended = gEngfuncs.Cvar_Get( "r_lighting_extended", "1", FCVAR_ARCHIVE, "allow to get lighting from world and bmodels" ); + r_lighting_modulate = gEngfuncs.Cvar_Get( "r_lighting_modulate", "0.6", FCVAR_ARCHIVE, "lightstyles modulate scale" ); + r_lighting_ambient = gEngfuncs.Cvar_Get( "r_lighting_ambient", "0.3", FCVAR_ARCHIVE, "map ambient lighting scale" ); + r_novis = gEngfuncs.Cvar_Get( "r_novis", "0", 0, "ignore vis information (perfomance test)" ); + r_nocull = gEngfuncs.Cvar_Get( "r_nocull", "0", 0, "ignore frustrum culling (perfomance test)" ); + r_detailtextures = gEngfuncs.Cvar_Get( "r_detailtextures", "1", FCVAR_ARCHIVE, "enable detail textures support, use '2' for autogenerate detail.txt" ); + r_lockpvs = gEngfuncs.Cvar_Get( "r_lockpvs", "0", FCVAR_CHEAT, "lockpvs area at current point (pvs test)" ); + r_lockfrustum = gEngfuncs.Cvar_Get( "r_lockfrustum", "0", FCVAR_CHEAT, "lock frustrum area at current point (cull test)" ); + r_dynamic = gEngfuncs.Cvar_Get( "r_dynamic", "1", FCVAR_ARCHIVE, "allow dynamic lighting (dlights, lightstyles)" ); + r_traceglow = gEngfuncs.Cvar_Get( "r_traceglow", "1", FCVAR_ARCHIVE, "cull flares behind models" ); + r_lightmap = gEngfuncs.Cvar_Get( "r_lightmap", "0", FCVAR_CHEAT, "lightmap debugging tool" ); + r_drawentities = gEngfuncs.Cvar_Get( "r_drawentities", "1", FCVAR_CHEAT, "render entities" ); + r_decals = gEngfuncs.pfnGetCvarPointer( "r_decals", 0 ); + r_showhull = gEngfuncs.pfnGetCvarPointer( "r_showhull", 0 ); + + gl_extensions = gEngfuncs.Cvar_Get( "gl_allow_extensions", "1", FCVAR_GLCONFIG, "allow gl_extensions" ); + gl_texture_nearest = gEngfuncs.Cvar_Get( "gl_texture_nearest", "0", FCVAR_ARCHIVE, "disable texture filter" ); + gl_lightmap_nearest = gEngfuncs.Cvar_Get( "gl_lightmap_nearest", "0", FCVAR_ARCHIVE, "disable lightmap filter" ); + gl_check_errors = gEngfuncs.Cvar_Get( "gl_check_errors", "1", FCVAR_ARCHIVE, "ignore video engine errors" ); + gl_vsync = gEngfuncs.pfnGetCvarPointer( "gl_vsync", 0 ); + gl_detailscale = gEngfuncs.Cvar_Get( "gl_detailscale", "4.0", FCVAR_ARCHIVE, "default scale applies while auto-generate list of detail textures" ); + gl_texture_anisotropy = gEngfuncs.Cvar_Get( "gl_anisotropy", "8", FCVAR_ARCHIVE, "textures anisotropic filter" ); + gl_texture_lodbias = gEngfuncs.Cvar_Get( "gl_texture_lodbias", "0.0", FCVAR_ARCHIVE, "LOD bias for mipmapped textures (perfomance|quality)" ); + gl_keeptjunctions = gEngfuncs.Cvar_Get( "gl_keeptjunctions", "1", FCVAR_ARCHIVE, "removing tjuncs causes blinking pixels" ); + gl_emboss_scale = gEngfuncs.Cvar_Get( "gl_emboss_scale", "0", FCVAR_ARCHIVE|FCVAR_LATCH, "fake bumpmapping scale" ); + gl_showtextures = gEngfuncs.pfnGetCvarPointer( "r_showtextures", 0 ); + gl_finish = gEngfuncs.Cvar_Get( "gl_finish", "0", FCVAR_ARCHIVE, "use glFinish instead of glFlush" ); + gl_nosort = gEngfuncs.Cvar_Get( "gl_nosort", "0", FCVAR_ARCHIVE, "disable sorting of translucent surfaces" ); + gl_clear = gEngfuncs.Cvar_Get( "gl_clear", "0", FCVAR_ARCHIVE, "clearing screen after each frame" ); + gl_test = gEngfuncs.Cvar_Get( "gl_test", "0", 0, "engine developer cvar for quick testing new features" ); + gl_wireframe = gEngfuncs.Cvar_Get( "gl_wireframe", "0", FCVAR_ARCHIVE|FCVAR_SPONLY, "show wireframe overlay" ); + gl_msaa = gEngfuncs.Cvar_Get( "gl_msaa", "1", FCVAR_ARCHIVE, "enable or disable multisample anti-aliasing" ); + gl_stencilbits = gEngfuncs.Cvar_Get( "gl_stencilbits", "8", FCVAR_GLCONFIG, "pixelformat stencil bits (0 - auto)" ); + gl_round_down = gEngfuncs.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 = gEngfuncs.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 = gEngfuncs.pfnGetCvarPointer( "gamma", 0 ); + vid_brightness = gEngfuncs.pfnGetCvarPointer( "brightness", 0 ); + + tracerred = gEngfuncs.Cvar_Get( "tracerred", "0.8", 0, "tracer red component weight ( 0 - 1.0 )" ); + tracergreen = gEngfuncs.Cvar_Get( "tracergreen", "0.8", 0, "tracer green component weight ( 0 - 1.0 )" ); + tracerblue = gEngfuncs.Cvar_Get( "tracerblue", "0.4", 0, "tracer blue component weight ( 0 - 1.0 )" ); + traceralpha = gEngfuncs.Cvar_Get( "traceralpha", "0.5", 0, "tracer alpha amount ( 0 - 1.0 )" ); + + cl_lightstyle_lerping = gEngfuncs.pfnGetCvarPointer( "cl_lightstyle_lerping", 0 ); + + gEngfuncs.Cmd_AddCommand( "r_info", R_RenderInfo_f, "display renderer info" ); + gEngfuncs.Cmd_AddCommand( "timerefresh", SCR_TimeRefresh_f, "turn quickly and print rendering statistcs" ); + + // give initial OpenGL configuration + gEngfuncs.Cbuf_SetOpenGLConfigHack( true ); + gEngfuncs.Cbuf_AddText( "exec opengl.cfg\n" ); + gEngfuncs.Cbuf_Execute(); + gEngfuncs.Cbuf_SetOpenGLConfigHack( false ); + + // apply actual video mode to window + gEngfuncs.Cbuf_AddText( "exec video.cfg\n" ); + gEngfuncs.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 = gEngfuncs.Cvar_Get( "r_vbo", def, flags, "draw world using VBO" ); + r_vbo_dlightmode = gEngfuncs.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; +} + +/* +================= +GL_RemoveCommands +================= +*/ +void GL_RemoveCommands( void ) +{ + gEngfuncs.Cmd_RemoveCommand( "r_info" ); +} + +/* +=============== +R_Init +=============== +*/ +qboolean R_Init( void ) +{ + if( glw_state.initialized ) + return true; + + GL_InitCommands(); + GL_InitRandomTable(); + + GL_SetDefaultState(); + + // create the window and set up the context + if( !gEngfuncs.R_Init_Video( REF_GL )) // request GL context + { + GL_RemoveCommands(); + gEngfuncs.R_Free_Video(); + + gEngfuncs.Host_Error( "Can't initialize video subsystem\nProbably driver was not installed" ); + return false; + } + + r_temppool = Mem_AllocPool( "Render Zone" ); + + GL_SetDefaults(); + R_CheckVBO(); + R_InitImages(); + R_SpriteInit(); + R_StudioInit(); + R_AliasInit(); + R_ClearDecals(); + R_ClearScene(); + + return true; +} + +/* +=============== +R_Shutdown +=============== +*/ +void R_Shutdown( void ) +{ + if( !glw_state.initialized ) + return; + + GL_RemoveCommands(); + R_ShutdownImages(); + + Mem_FreePool( &r_temppool ); + + // shut down OS specific OpenGL stuff like contexts, etc. + gEngfuncs.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; + + gEngfuncs.Con_Printf( S_OPENGL_ERROR "%s (called at %s:%i)\n", GL_ErrorString( err ), filename, fileline ); +} + +void GL_SetupAttributes( int safegl ) +{ + int context_flags = 0; // REFTODO!!!!! + int samples = 0; + +#ifdef XASH_GLES + gEngfuncs.GL_SetAttribute( REF_GL_CONTEXT_PROFILE_MASK, REF_GL_CONTEXT_PROFILE_ES ); + gEngfuncs.GL_SetAttribute( REF_GL_CONTEXT_EGL, 1 ); +#ifdef XASH_NANOGL + gEngfuncs.GL_SetAttribute( REF_GL_CONTEXT_MAJOR_VERSION, 1 ); + gEngfuncs.GL_SetAttribute( REF_GL_CONTEXT_MINOR_VERSION, 1 ); +#elif defined( XASH_WES ) || defined( XASH_REGAL ) + gEngfuncs.GL_SetAttribute( REF_GL_CONTEXT_MAJOR_VERSION, 2 ); + gEngfuncs.GL_SetAttribute( REF_GL_CONTEXT_MINOR_VERSION, 0 ); +#endif +#else // GL1.x +#ifndef XASH_GL_STATIC + if( gEngfuncs.Sys_CheckParm( "-gldebug" ) ) + { + gEngfuncs.Con_Reportf( "Creating an extended GL context for debug...\n" ); + SetBits( context_flags, FCONTEXT_DEBUG_ARB ); + gEngfuncs.GL_SetAttribute( REF_GL_CONTEXT_FLAGS, REF_GL_CONTEXT_DEBUG_FLAG ); + glw_state.extended = true; + } +#endif // XASH_GL_STATIC + if( gEngfuncs.Sys_CheckParm( "-glcore" )) + { + SetBits( context_flags, FCONTEXT_CORE_PROFILE ); + + gEngfuncs.GL_SetAttribute( REF_GL_CONTEXT_PROFILE_MASK, REF_GL_CONTEXT_PROFILE_CORE ); + } + else + { + gEngfuncs.GL_SetAttribute( REF_GL_CONTEXT_PROFILE_MASK, REF_GL_CONTEXT_PROFILE_COMPATIBILITY ); + } +#endif // XASH_GLES + + if( safegl > SAFE_DONTCARE ) + { + safegl = -1; // can't retry anymore, can only shutdown engine + return; + } + + gEngfuncs.Con_Printf( "Trying safe opengl mode %d\n", safegl ); + + if( safegl == SAFE_DONTCARE ) + return; + + gEngfuncs.GL_SetAttribute( REF_GL_DOUBLEBUFFER, 1 ); + + if( safegl < SAFE_NOACC ) + gEngfuncs.GL_SetAttribute( REF_GL_ACCELERATED_VISUAL, 1 ); + + gEngfuncs.Con_Printf( "bpp %d\n", glw_state.desktopBitsPixel ); + + if( safegl < SAFE_NOSTENCIL ) + gEngfuncs.GL_SetAttribute( REF_GL_STENCIL_SIZE, gl_stencilbits->value ); + + if( safegl < SAFE_NOALPHA ) + gEngfuncs.GL_SetAttribute( REF_GL_ALPHA_SIZE, 8 ); + + if( safegl < SAFE_NODEPTH ) + gEngfuncs.GL_SetAttribute( REF_GL_DEPTH_SIZE, 24 ); + else + gEngfuncs.GL_SetAttribute( REF_GL_DEPTH_SIZE, 8 ); + + if( safegl < SAFE_NOCOLOR ) + { + if( glw_state.desktopBitsPixel >= 24 ) + { + gEngfuncs.GL_SetAttribute( REF_GL_RED_SIZE, 8 ); + gEngfuncs.GL_SetAttribute( REF_GL_GREEN_SIZE, 8 ); + gEngfuncs.GL_SetAttribute( REF_GL_BLUE_SIZE, 8 ); + } + else if( glw_state.desktopBitsPixel >= 16 ) + { + gEngfuncs.GL_SetAttribute( REF_GL_RED_SIZE, 5 ); + gEngfuncs.GL_SetAttribute( REF_GL_GREEN_SIZE, 6 ); + gEngfuncs.GL_SetAttribute( REF_GL_BLUE_SIZE, 5 ); + } + else + { + gEngfuncs.GL_SetAttribute( REF_GL_RED_SIZE, 3 ); + gEngfuncs.GL_SetAttribute( REF_GL_GREEN_SIZE, 3 ); + gEngfuncs.GL_SetAttribute( REF_GL_BLUE_SIZE, 2 ); + } + } + + if( safegl < SAFE_NOMSAA ) + { + switch( (int)gEngfuncs.pfnGetCvarFloat( "gl_wgl_msaa_samples" )) + { + case 2: + case 4: + case 8: + case 16: + samples = gEngfuncs.pfnGetCvarFloat( "gl_wgl_msaa_samples" ); + break; + default: + samples = 0; // don't use, because invalid parameter is passed + } + + if( samples ) + { + gEngfuncs.GL_SetAttribute( REF_GL_MULTISAMPLEBUFFERS, 1 ); + gEngfuncs.GL_SetAttribute( REF_GL_MULTISAMPLESAMPLES, samples ); + + glConfig.max_multisamples = samples; + } + else + { + gEngfuncs.GL_SetAttribute( REF_GL_MULTISAMPLEBUFFERS, 0 ); + gEngfuncs.GL_SetAttribute( REF_GL_MULTISAMPLESAMPLES, 0 ); + + glConfig.max_multisamples = 0; + } + } + else + { + gEngfuncs.Cvar_Set( "gl_wgl_msaa_samples", "0" ); + } +} + +void GL_OnContextCreated( void ) +{ + int colorBits[3]; +#ifdef XASH_NANOGL + nanoGL_Init(); +#endif + + gEngfuncs.GL_GetAttribute( REF_GL_RED_SIZE, &colorBits[0] ); + gEngfuncs.GL_GetAttribute( REF_GL_GREEN_SIZE, &colorBits[1] ); + gEngfuncs.GL_GetAttribute( REF_GL_BLUE_SIZE, &colorBits[2] ); + glConfig.color_bits = colorBits[0] + colorBits[1] + colorBits[2]; + + gEngfuncs.GL_GetAttribute( REF_GL_ALPHA_SIZE, &glConfig.alpha_bits ); + gEngfuncs.GL_GetAttribute( REF_GL_DEPTH_SIZE, &glConfig.depth_bits ); + gEngfuncs.GL_GetAttribute( REF_GL_STENCIL_SIZE, &glConfig.stencil_bits ); + glState.stencilEnabled = glConfig.stencil_bits ? true : false; + + gEngfuncs.GL_GetAttribute( REF_GL_MULTISAMPLESAMPLES, &glConfig.msaasamples ); + +#ifdef XASH_WES + void wes_init(); + wes_init(); +#endif +} + diff --git a/engine/client/gl_rlight.c b/ref_gl/gl_rlight.c similarity index 92% rename from engine/client/gl_rlight.c rename to ref_gl/gl_rlight.c index 0ca73a54..de46d492 100644 --- a/engine/client/gl_rlight.c +++ b/ref_gl/gl_rlight.c @@ -13,12 +13,11 @@ 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" #include "studio.h" +#include "mathlib.h" +#include "ref_params.h" /* ============================================================================= @@ -37,25 +36,26 @@ void CL_RunLightStyles( void ) { int i, k, flight, clight; float l, lerpfrac, backlerp; - float frametime = (cl.time - cl.oldtime); + float frametime = (gpGlobals->time - gpGlobals->oldtime); float scale; lightstyle_t *ls; - if( !cl.worldmodel ) return; + if( !WORLDMODEL ) return; scale = r_lighting_modulate->value; // light animations // 'm' is normal light, 'a' is no light, 'z' is double bright - for( i = 0, ls = cl.lightstyles; i < MAX_LIGHTSTYLES; i++, ls++ ) + for( i = 0; i < MAX_LIGHTSTYLES; i++ ) { - if( !cl.worldmodel->lightdata ) + ls = gEngfuncs.GetLightStyle( i ); + if( !WORLDMODEL->lightdata ) { tr.lightstylevalue[i] = 256 * 256; continue; } - if( !cl.paused && frametime <= 0.1f ) + if( !ENGINE_GET_PARM( PARAM_GAMEPAUSED ) && frametime <= 0.1f ) ls->time += frametime; // evaluate local time flight = (int)Q_floor( ls->time * 10 ); @@ -151,14 +151,15 @@ void R_PushDlights( void ) int i; tr.dlightframecount = tr.framecount; - l = cl_dlights; - RI.currententity = clgame.entities; + RI.currententity = gEngfuncs.GetEntityByIndex( 0 ); RI.currentmodel = RI.currententity->model; for( i = 0; i < MAX_DLIGHTS; i++, l++ ) { - if( l->die < cl.time || !l->radius ) + l = gEngfuncs.GetDynamicLight( i ); + + if( l->die < gpGlobals->time || !l->radius ) continue; if( GL_FrustumCullSphere( &RI.frustum, l->origin, l->radius, 15 )) @@ -178,9 +179,11 @@ int R_CountDlights( void ) dlight_t *l; int i, numDlights = 0; - for( i = 0, l = cl_dlights; i < MAX_DLIGHTS; i++, l++ ) + for( i = 0; i < MAX_DLIGHTS; i++ ) { - if( l->die < cl.time || !l->radius ) + l = gEngfuncs.GetDynamicLight( i ); + + if( l->die < gpGlobals->time || !l->radius ) continue; numDlights++; @@ -299,7 +302,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, if( !surf->samples ) return true; - sample_size = Mod_SampleSizeForFace( surf ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( surf ); smax = (info->lightextents[0] / sample_size) + 1; tmax = (info->lightextents[1] / sample_size) + 1; ds /= sample_size; @@ -346,9 +349,9 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, } else { - cv->r += LightToTexGamma( lm->r ) * scale; - cv->g += LightToTexGamma( lm->g ) * scale; - cv->b += LightToTexGamma( lm->b ) * scale; + cv->r += gEngfuncs.LightToTexGamma( lm->r ) * scale; + cv->g += gEngfuncs.LightToTexGamma( lm->g ) * scale; + cv->b += gEngfuncs.LightToTexGamma( lm->b ) * scale; } lm += size; // skip to next lightmap @@ -388,23 +391,26 @@ 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; // get light from bmodels too if( CVAR_TO_BOOL( r_lighting_extended )) - maxEnts = clgame.pmove->numphysent; + maxEnts = MAX_PHYSENTS; // check all the bsp-models for( i = 0; i < maxEnts; i++ ) { - physent_t *pe = &clgame.pmove->physents[i]; + physent_t *pe = gEngfuncs.EV_GetPhysent( i ); vec3_t offset, start_l, end_l; mnode_t *pnodes; matrix4x4 matrix; + if( !pe ) + break; + if( !pe->model || pe->model->type != mod_brush ) continue; // skip non-bsp models diff --git a/engine/client/gl_rmain.c b/ref_gl/gl_rmain.c similarity index 67% rename from engine/client/gl_rmain.c rename to ref_gl/gl_rmain.c index 46813497..97c257ba 100644 --- a/engine/client/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 ) @@ -42,7 +39,7 @@ static int R_RankForRenderMode( int rendermode ) return 0; } -void R_AllowFog( int allowed ) +void R_AllowFog( qboolean allowed ) { static int isFogEnabled; @@ -199,7 +196,7 @@ R_PushScene void R_PushScene( void ) { if( ++tr.draw_stack_pos >= MAX_DRAW_STACK ) - Host_Error( "draw stack overflow\n" ); + gEngfuncs.Host_Error( "draw stack overflow\n" ); tr.draw_list = &tr.draw_stack[tr.draw_stack_pos]; } @@ -212,7 +209,7 @@ R_PopScene void R_PopScene( void ) { if( --tr.draw_stack_pos < 0 ) - Host_Error( "draw stack underflow\n" ); + gEngfuncs.Host_Error( "draw stack underflow\n" ); tr.draw_list = &tr.draw_stack[tr.draw_stack_pos]; } @@ -226,6 +223,11 @@ void R_ClearScene( void ) tr.draw_list->num_solid_entities = 0; tr.draw_list->num_trans_entities = 0; tr.draw_list->num_beam_entities = 0; + + // clear the scene befor start new frame + if( gEngfuncs.drawFuncs->R_ClearScene != NULL ) + gEngfuncs.drawFuncs->R_ClearScene(); + } /* @@ -244,7 +246,7 @@ qboolean R_AddEntity( struct cl_entity_s *clent, int type ) if( FBitSet( clent->curstate.effects, EF_NODRAW )) return false; // done - if( !R_ModelOpaque( clent->curstate.rendermode ) && CL_FxBlend( clent ) <= 0 ) + if( !R_ModelOpaque( clent->curstate.rendermode ) && gEngfuncs.CL_FxBlend( clent ) <= 0 ) return true; // invisible if( type == ET_FRAGMENTED ) @@ -281,7 +283,7 @@ static void R_Clear( int bitMask ) { int bits; - if( CL_IsDevOverviewMode( )) + if( ENGINE_GET_PARM( PARM_DEV_OVERVIEW )) pglClearColor( 0.0f, 1.0f, 0.0f, 1.0f ); // green background (Valve rules) else pglClearColor( 0.5f, 0.5f, 0.5f, 1.0f ); @@ -318,8 +320,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; } @@ -330,12 +332,12 @@ R_SetupFrustum */ void R_SetupFrustum( void ) { - ref_overview_t *ov = &clgame.overView; + const ref_overview_t *ov = gEngfuncs.GetOverviewParms(); - if( RP_NORMALPASS() && ( cl.local.waterlevel >= 3 )) + if( RP_NORMALPASS() && ( ENGINE_GET_PARM( PARM_WATER_LEVEL ) >= 3 )) { - RI.fov_x = atan( tan( DEG2RAD( RI.fov_x ) / 2 ) * ( 0.97 + sin( cl.time * 1.5 ) * 0.03 )) * 2 / (M_PI / 180.0); - RI.fov_y = atan( tan( DEG2RAD( RI.fov_y ) / 2 ) * ( 1.03 - sin( cl.time * 1.5 ) * 0.03 )) * 2 / (M_PI / 180.0); + RI.fov_x = atan( tan( DEG2RAD( RI.fov_x ) / 2 ) * ( 0.97 + sin( gpGlobals->time * 1.5 ) * 0.03 )) * 2 / (M_PI / 180.0); + RI.fov_y = atan( tan( DEG2RAD( RI.fov_y ) / 2 ) * ( 1.03 - sin( gpGlobals->time * 1.5 ) * 0.03 )) * 2 / (M_PI / 180.0); } // build the transformation matrix for the given view angles @@ -365,7 +367,7 @@ static void R_SetupProjectionMatrix( matrix4x4 m ) if( RI.drawOrtho ) { - ref_overview_t *ov = &clgame.overView; + const ref_overview_t *ov = gEngfuncs.GetOverviewParms(); Matrix4x4_CreateOrtho( m, ov->xLeft, ov->xRight, ov->yTop, ov->yBottom, ov->zNear, ov->zFar ); return; } @@ -424,7 +426,7 @@ void R_RotateForEntity( cl_entity_t *e ) { float scale = 1.0f; - if( e == clgame.entities ) + if( e == gEngfuncs.GetEntityByIndex( 0 ) ) { R_LoadIdentity(); return; @@ -450,7 +452,7 @@ void R_TranslateForEntity( cl_entity_t *e ) { float scale = 1.0f; - if( e == clgame.entities ) + if( e == gEngfuncs.GetEntityByIndex( 0 ) ) { R_LoadIdentity(); return; @@ -475,7 +477,7 @@ R_FindViewLeaf void R_FindViewLeaf( void ) { RI.oldviewleaf = RI.viewleaf; - RI.viewleaf = Mod_PointInLeaf( RI.pvsorigin, cl.worldmodel->nodes ); + RI.viewleaf = gEngfuncs.Mod_PointInLeaf( RI.pvsorigin, WORLDMODEL->nodes ); } /* @@ -521,10 +523,10 @@ void R_SetupGL( qboolean set_gl_state ) int x, x2, y, y2; // set up viewport (main, playersetup) - x = floor( RI.viewport[0] * glState.width / glState.width ); - x2 = ceil(( RI.viewport[0] + RI.viewport[2] ) * glState.width / glState.width ); - y = floor( glState.height - RI.viewport[1] * glState.height / glState.height ); - y2 = ceil( glState.height - ( RI.viewport[1] + RI.viewport[3] ) * glState.height / glState.height ); + x = floor( RI.viewport[0] * gpGlobals->width / gpGlobals->width ); + x2 = ceil(( RI.viewport[0] + RI.viewport[2] ) * gpGlobals->width / gpGlobals->width ); + y = floor( gpGlobals->height - RI.viewport[1] * gpGlobals->height / gpGlobals->height ); + y2 = ceil( gpGlobals->height - ( RI.viewport[1] + RI.viewport[3] ) * gpGlobals->height / gpGlobals->height ); pglViewport( x, y2, x2 - x, y - y2 ); } @@ -659,9 +661,9 @@ static void R_CheckFog( void ) int i, cnt, count; // quake global fog - if( Host_IsQuakeCompatible( )) + if( ENGINE_GET_PARM( PARM_QUAKE_COMPATIBLE )) { - if( !clgame.movevars.fog_settings ) + if( !MOVEVARS->fog_settings ) { if( pglIsEnabled( GL_FOG )) pglDisable( GL_FOG ); @@ -670,10 +672,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; @@ -684,24 +686,24 @@ static void R_CheckFog( void ) RI.fogEnabled = false; - if( RI.onlyClientDraw || cl.local.waterlevel < 3 || !RI.drawWorld || !RI.viewleaf ) + if( RI.onlyClientDraw || ENGINE_GET_PARM( PARM_WATER_LEVEL ) < 3 || !RI.drawWorld || !RI.viewleaf ) { if( RI.cached_waterlevel == 3 ) - { + { // in some cases waterlevel jumps from 3 to 1. Catch it - RI.cached_waterlevel = cl.local.waterlevel; + RI.cached_waterlevel = ENGINE_GET_PARM( PARM_WATER_LEVEL ); RI.cached_contents = CONTENTS_EMPTY; if( !RI.fogCustom ) pglDisable( GL_FOG ); } return; } - ent = CL_GetWaterEntity( RI.vieworg ); + ent = gEngfuncs.CL_GetWaterEntity( RI.vieworg ); if( ent && ent->model && ent->model->type == mod_brush && ent->curstate.skin < 0 ) cnt = ent->curstate.skin; else cnt = RI.viewleaf->contents; - RI.cached_waterlevel = cl.local.waterlevel; + RI.cached_waterlevel = ENGINE_GET_PARM( PARM_WATER_LEVEL ); if( !IsLiquidContents( RI.cached_contents ) && IsLiquidContents( cnt )) { @@ -782,7 +784,7 @@ void R_DrawFog( void ) if( !RI.fogEnabled ) return; pglEnable( GL_FOG ); - if( Host_IsQuakeCompatible( )) + if( ENGINE_GET_PARM( PARM_QUAKE_COMPATIBLE )) pglFogi( GL_FOG_MODE, GL_EXP2 ); else pglFogi( GL_FOG_MODE, GL_EXP ); pglFogf( GL_FOG_DENSITY, RI.fogDensity ); @@ -854,14 +856,14 @@ void R_DrawEntitiesOnList( void ) GL_CheckForErrors(); if( !RI.onlyClientDraw ) - { - CL_DrawBeams( false ); + { + gEngfuncs.CL_DrawEFX( tr.frametime, false ); } GL_CheckForErrors(); if( RI.drawWorld ) - clgame.dllFuncs.pfnDrawNormalTriangles(); + gEngfuncs.pfnDrawNormalTriangles(); GL_CheckForErrors(); @@ -873,7 +875,7 @@ void R_DrawEntitiesOnList( void ) // handle studiomodels with custom rendermodes on texture if( RI.currententity->curstate.rendermode != kRenderNormal ) - tr.blend = CL_FxBlend( RI.currententity ) / 255.0f; + tr.blend = gEngfuncs.CL_FxBlend( RI.currententity ) / 255.0f; else tr.blend = 1.0f; // draw as solid but sorted by distance if( tr.blend <= 0.0f ) continue; @@ -905,7 +907,7 @@ void R_DrawEntitiesOnList( void ) if( RI.drawWorld ) { pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - clgame.dllFuncs.pfnDrawTransparentTriangles (); + gEngfuncs.pfnDrawTransparentTriangles (); } GL_CheckForErrors(); @@ -913,9 +915,7 @@ void R_DrawEntitiesOnList( void ) if( !RI.onlyClientDraw ) { R_AllowFog( false ); - CL_DrawBeams( true ); - CL_DrawParticles( tr.frametime ); - CL_DrawTracers( tr.frametime ); + gEngfuncs.CL_DrawEFX( tr.frametime, true ); R_AllowFog( true ); } @@ -925,7 +925,7 @@ void R_DrawEntitiesOnList( void ) if( !RI.onlyClientDraw ) R_DrawViewModel(); - CL_ExtraUpdate(); + gEngfuncs.CL_ExtraUpdate(); GL_CheckForErrors(); } @@ -939,12 +939,12 @@ R_SetupRefParams must be called right before */ void R_RenderScene( void ) { - if( !cl.worldmodel && RI.drawWorld ) - Host_Error( "R_RenderView: NULL worldmodel\n" ); + if( !WORLDMODEL && RI.drawWorld ) + gEngfuncs.Host_Error( "R_RenderView: NULL worldmodel\n" ); // frametime is valid only for normal pass if( RP_NORMALPASS( )) - tr.frametime = cl.time - cl.oldtime; + tr.frametime = gpGlobals->time - gpGlobals->oldtime; else tr.frametime = 0.0; // begin a new frame @@ -964,7 +964,7 @@ void R_RenderScene( void ) R_DrawWorld(); R_CheckFog(); - CL_ExtraUpdate (); // don't let sound get messed up if going slow + gEngfuncs.CL_ExtraUpdate (); // don't let sound get messed up if going slow R_DrawEntitiesOnList(); @@ -985,7 +985,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 +1005,7 @@ qboolean R_DoResetGamma( void ) default: return false; } +#endif } /* @@ -1016,14 +1017,15 @@ void R_BeginFrame( qboolean clearScene ) { glConfig.softwareGammaUpdate = false; // in case of possible fails - if(( gl_clear->value || CL_IsDevOverviewMode( )) && clearScene && cls.state != ca_cinematic ) + if(( gl_clear->value || ENGINE_GET_PARM( PARM_DEV_OVERVIEW )) && + clearScene && ENGINE_GET_PARM( PARM_CONNSTATE ) != ca_cinematic ) { pglClear( GL_COLOR_BUFFER_BIT ); } if( R_DoResetGamma( )) { - BuildGammaTable( 1.8f, 0.0f ); + gEngfuncs.BuildGammaTable( 1.8f, 0.0f ); glConfig.softwareGammaUpdate = true; GL_RebuildLightmaps(); glConfig.softwareGammaUpdate = false; @@ -1034,7 +1036,7 @@ void R_BeginFrame( qboolean clearScene ) } else if( FBitSet( vid_gamma->flags, FCVAR_CHANGED ) || FBitSet( vid_brightness->flags, FCVAR_CHANGED )) { - BuildGammaTable( vid_gamma->value, vid_brightness->value ); + gEngfuncs.BuildGammaTable( vid_gamma->value, vid_brightness->value ); glConfig.softwareGammaUpdate = true; GL_RebuildLightmaps(); glConfig.softwareGammaUpdate = false; @@ -1049,10 +1051,7 @@ void R_BeginFrame( qboolean clearScene ) if( FBitSet( gl_texture_nearest->flags|gl_lightmap_nearest->flags|gl_texture_anisotropy->flags|gl_texture_lodbias->flags, FCVAR_CHANGED )) R_SetTextureParameters(); - // swapinterval stuff - GL_UpdateSwapInterval(); - - CL_ExtraUpdate (); + gEngfuncs.CL_ExtraUpdate (); } /* @@ -1093,10 +1092,10 @@ void R_SetupRefParams( const ref_viewpass_t *rvp ) R_RenderFrame =============== */ -void R_RenderFrame( const ref_viewpass_t *rvp ) +int R_RenderFrame( const ref_viewpass_t *rvp ) { if( r_norefresh->value ) - return; + return 1; // setup the initial render params R_SetupRefParams( rvp ); @@ -1113,16 +1112,16 @@ void R_RenderFrame( const ref_viewpass_t *rvp ) } // completely override rendering - if( clgame.drawFuncs.GL_RenderFrame != NULL ) + if( gEngfuncs.drawFuncs->GL_RenderFrame != NULL ) { tr.fCustomRendering = true; - if( clgame.drawFuncs.GL_RenderFrame( rvp )) + if( gEngfuncs.drawFuncs->GL_RenderFrame( rvp )) { R_GatherPlayerLight(); tr.realframecount++; tr.fResetVis = true; - return; + return 1; } } @@ -1132,6 +1131,8 @@ void R_RenderFrame( const ref_viewpass_t *rvp ) tr.realframecount++; // right called after viewmodel events R_RenderScene(); + + return 1; } /* @@ -1143,12 +1144,7 @@ void R_EndFrame( void ) { // flush any remaining 2D bits R_Set2DMode( false ); - -#ifdef XASH_SDL - SDL_GL_SwapWindow( host.hWnd ); -#elif defined __ANDROID__ // For direct android backend - Android_SwapBuffers(); -#endif + gEngfuncs.GL_SwapBuffers(); } /* @@ -1177,383 +1173,3 @@ void R_DrawCubemapView( const vec3_t origin, const vec3_t angles, int size ) RI.viewleaf = NULL; // force markleafs next frame } - -static int GL_RenderGetParm( int parm, int arg ) -{ - gl_texture_t *glt; - - switch( parm ) - { - case PARM_TEX_WIDTH: - glt = R_GetTexture( arg ); - return glt->width; - case PARM_TEX_HEIGHT: - glt = R_GetTexture( arg ); - return glt->height; - case PARM_TEX_SRC_WIDTH: - glt = R_GetTexture( arg ); - return glt->srcWidth; - case PARM_TEX_SRC_HEIGHT: - glt = R_GetTexture( arg ); - return glt->srcHeight; - case PARM_TEX_GLFORMAT: - glt = R_GetTexture( arg ); - return glt->format; - case PARM_TEX_ENCODE: - glt = R_GetTexture( arg ); - return glt->encode; - case PARM_TEX_MIPCOUNT: - glt = R_GetTexture( arg ); - return glt->numMips; - case PARM_TEX_DEPTH: - glt = R_GetTexture( arg ); - return glt->depth; - case PARM_BSP2_SUPPORTED: -#ifdef SUPPORT_BSP2_FORMAT - return 1; -#endif - return 0; - case PARM_TEX_SKYBOX: - Assert( arg >= 0 && arg < 6 ); - return tr.skyboxTextures[arg]; - case PARM_TEX_SKYTEXNUM: - return tr.skytexturenum; - case PARM_TEX_LIGHTMAP: - 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 ); - case PARAM_GAMEPAUSED: - return cl.paused; - case PARM_WIDESCREEN: - return glState.wideScreen; - case PARM_FULLSCREEN: - return glState.fullScreen; - case PARM_SCREEN_WIDTH: - return glState.width; - case PARM_SCREEN_HEIGHT: - return glState.height; - case PARM_CLIENT_INGAME: - return CL_IsInGame(); - case PARM_MAX_ENTITIES: - return clgame.maxEntities; - case PARM_TEX_TARGET: - glt = R_GetTexture( arg ); - return glt->target; - case PARM_TEX_TEXNUM: - glt = R_GetTexture( arg ); - return glt->texnum; - case PARM_TEX_FLAGS: - glt = R_GetTexture( arg ); - return glt->flags; - case PARM_FEATURES: - return host.features; - case PARM_ACTIVE_TMU: - return glState.activeTMU; - case PARM_LIGHTSTYLEVALUE: - arg = bound( 0, arg, MAX_LIGHTSTYLES - 1 ); - return tr.lightstylevalue[arg]; - case PARM_MAP_HAS_DELUXE: - return FBitSet( world.flags, FWORLD_HAS_DELUXEMAP ); - case PARM_MAX_IMAGE_UNITS: - return GL_MaxTextureUnits(); - case PARM_CLIENT_ACTIVE: - return (cls.state == ca_active); - case PARM_REBUILD_GAMMA: - return glConfig.softwareGammaUpdate; - 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] ); - return LM_SAMPLE_SIZE; - case PARM_GL_CONTEXT_TYPE: - return glConfig.context; - case PARM_GLES_WRAPPER: - return glConfig.wrapper; - case PARM_STENCIL_ACTIVE: - return glState.stencilEnabled; - case PARM_WATER_ALPHA: - return FBitSet( world.flags, FWORLD_WATERALPHA ); - } - return 0; -} - -static void R_GetDetailScaleForTexture( int texture, float *xScale, float *yScale ) -{ - gl_texture_t *glt = R_GetTexture( texture ); - - if( xScale ) *xScale = glt->xscale; - if( yScale ) *yScale = glt->yscale; -} - -static void R_GetExtraParmsForTexture( int texture, byte *red, byte *green, byte *blue, byte *density ) -{ - gl_texture_t *glt = R_GetTexture( texture ); - - if( red ) *red = glt->fogParams[0]; - if( green ) *green = glt->fogParams[1]; - if( blue ) *blue = glt->fogParams[2]; - if( density ) *density = glt->fogParams[3]; -} - -/* -================= -R_EnvShot - -================= -*/ -static void R_EnvShot( const float *vieworg, const char *name, qboolean skyshot, int shotsize ) -{ - static vec3_t viewPoint; - - if( !COM_CheckString( name )) - return; - - if( cls.scrshot_action != scrshot_inactive ) - { - if( cls.scrshot_action != scrshot_skyshot && cls.scrshot_action != scrshot_envshot ) - Con_Printf( S_ERROR "R_%sShot: subsystem is busy, try for next frame.\n", skyshot ? "Sky" : "Env" ); - return; - } - - cls.envshot_vieworg = NULL; // use client view - Q_strncpy( cls.shotname, name, sizeof( cls.shotname )); - - if( vieworg ) - { - // make sure what viewpoint don't temporare - VectorCopy( vieworg, viewPoint ); - cls.envshot_vieworg = viewPoint; - cls.envshot_disable_vis = true; - } - - // make request for envshot - if( skyshot ) cls.scrshot_action = scrshot_skyshot; - else cls.scrshot_action = scrshot_envshot; - - // catch negative values - cls.envshot_viewsize = max( 0, shotsize ); -} - -static void R_SetCurrentEntity( cl_entity_t *ent ) -{ - RI.currententity = ent; - - // set model also - if( RI.currententity != NULL ) - { - RI.currentmodel = RI.currententity->model; - } -} - -static void R_SetCurrentModel( model_t *mod ) -{ - RI.currentmodel = mod; -} - -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 ); -} - -static lightstyle_t *CL_GetLightStyle( int number ) -{ - Assert( number >= 0 && number < MAX_LIGHTSTYLES ); - return &cl.lightstyles[number]; -} - -static dlight_t *CL_GetDynamicLight( int number ) -{ - Assert( number >= 0 && number < MAX_DLIGHTS ); - return &cl_dlights[number]; -} - -static dlight_t *CL_GetEntityLight( int number ) -{ - Assert( number >= 0 && number < MAX_ELIGHTS ); - return &cl_elights[number]; -} - -static float R_GetFrameTime( void ) -{ - return tr.frametime; -} - -static const char *GL_TextureName( unsigned int texnum ) -{ - return R_GetTexture( texnum )->name; -} - -const byte *GL_TextureData( unsigned int texnum ) -{ - rgbdata_t *pic = R_GetTexture( texnum )->original; - - if( pic != NULL ) - return pic->buffer; - return NULL; -} - -static const ref_overview_t *GL_GetOverviewParms( void ) -{ - return &clgame.overView; -} - -static void *R_Mem_Alloc( size_t cb, const char *filename, const int fileline ) -{ - return _Mem_Alloc( cls.mempool, cb, true, filename, fileline ); -} - -static void R_Mem_Free( void *mem, const char *filename, const int fileline ) -{ - if( !mem ) return; - _Mem_Free( mem, filename, fileline ); -} - -/* -========= -pfnGetFilesList - -========= -*/ -static char **pfnGetFilesList( const char *pattern, int *numFiles, int gamedironly ) -{ - static search_t *t = NULL; - - if( t ) Mem_Free( t ); // release prev search - - t = FS_Search( pattern, true, gamedironly ); - - if( !t ) - { - if( numFiles ) *numFiles = 0; - return NULL; - } - - if( numFiles ) *numFiles = t->numfilenames; - return t->filenames; -} - -static uint pfnFileBufferCRC32( const void *buffer, const int length ) -{ - uint modelCRC = 0; - - if( !buffer || length <= 0 ) - return modelCRC; - - CRC32_Init( &modelCRC ); - CRC32_ProcessBuffer( &modelCRC, buffer, length ); - return CRC32_Final( modelCRC ); -} - -/* -============= -CL_GenericHandle - -============= -*/ -const char *CL_GenericHandle( int fileindex ) -{ - if( fileindex < 0 || fileindex >= MAX_CUSTOM ) - return 0; - return cl.files_precache[fileindex]; -} - -static render_api_t gRenderAPI = -{ - GL_RenderGetParm, - R_GetDetailScaleForTexture, - R_GetExtraParmsForTexture, - CL_GetLightStyle, - CL_GetDynamicLight, - CL_GetEntityLight, - LightToTexGamma, - R_GetFrameTime, - R_SetCurrentEntity, - R_SetCurrentModel, - R_FatPVS, - R_StoreEfrags, - GL_FindTexture, - GL_TextureName, - GL_TextureData, - GL_LoadTexture, - GL_CreateTexture, - GL_LoadTextureArray, - GL_CreateTextureArray, - GL_FreeTexture, - DrawSingleDecal, - R_DecalSetupVerts, - R_EntityRemoveDecals, - (void*)AVI_LoadVideo, - (void*)AVI_GetVideoInfo, - (void*)AVI_GetVideoFrameNumber, - (void*)AVI_GetVideoFrame, - R_UploadStretchRaw, - (void*)AVI_FreeVideo, - (void*)AVI_IsActive, - S_StreamAviSamples, - NULL, - NULL, - GL_Bind, - GL_SelectTexture, - GL_LoadTexMatrixExt, - GL_LoadIdentityTexMatrix, - GL_CleanUpTextureUnits, - GL_TexGen, - GL_TextureTarget, - GL_SetTexCoordArrayMode, - GL_GetProcAddress, - GL_UpdateTexSize, - NULL, - NULL, - CL_DrawParticlesExternal, - R_EnvShot, - pfnSPR_LoadExt, - R_LightVec, - R_StudioGetTexture, - GL_GetOverviewParms, - CL_GenericHandle, - NULL, - NULL, - R_Mem_Alloc, - R_Mem_Free, - pfnGetFilesList, - pfnFileBufferCRC32, - COM_CompareFileTime, - Host_Error, - (void*)CL_ModelHandle, - pfnTime, - Cvar_Set, - S_FadeMusicVolume, - COM_SetRandomSeed, -}; - -/* -=============== -R_InitRenderAPI - -Initialize client external rendering -=============== -*/ -qboolean R_InitRenderAPI( void ) -{ - // make sure what render functions is cleared - memset( &clgame.drawFuncs, 0, sizeof( clgame.drawFuncs )); - - if( clgame.dllFuncs.pfnGetRenderInterface ) - { - if( clgame.dllFuncs.pfnGetRenderInterface( CL_RENDER_INTERFACE_VERSION, &gRenderAPI, &clgame.drawFuncs )) - { - Con_Reportf( "CL_LoadProgs: ^2initailized extended RenderAPI ^7ver. %i\n", CL_RENDER_INTERFACE_VERSION ); - return true; - } - - // make sure what render functions is cleared - memset( &clgame.drawFuncs, 0, sizeof( clgame.drawFuncs )); - - return false; // just tell user about problems - } - - // render interface is missed - return true; -} diff --git a/engine/client/gl_rmath.c b/ref_gl/gl_rmath.c similarity index 89% rename from engine/client/gl_rmath.c rename to ref_gl/gl_rmath.c index 30e591b4..d8aee626 100644 --- a/engine/client/gl_rmath.c +++ b/ref_gl/gl_rmath.c @@ -13,57 +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" - -/* -==================== -V_CalcFov -==================== -*/ -float V_CalcFov( float *fov_x, float width, float height ) -{ - float x, half_fov_y; - - if( *fov_x < 1.0f || *fov_x > 179.0f ) - *fov_x = 90.0f; // default value - - x = width / tan( DEG2RAD( *fov_x ) * 0.5f ); - half_fov_y = atan( height / x ); - - return RAD2DEG( half_fov_y ) * 2; -} - -/* -==================== -V_AdjustFov -==================== -*/ -void V_AdjustFov( float *fov_x, float *fov_y, float width, float height, qboolean lock_x ) -{ - float x, y; - - if( width * 3 == 4 * height || width * 4 == height * 5 ) - { - // 4:3 or 5:4 ratio - return; - } - - if( lock_x ) - { - *fov_y = 2 * atan((width * 3) / (height * 4) * tan( *fov_y * M_PI / 360.0 * 0.5 )) * 360 / M_PI; - return; - } - - y = V_CalcFov( fov_x, 640, 480 ); - x = *fov_x; - - *fov_x = V_CalcFov( &y, height, width ); - if( *fov_x < x ) *fov_x = x; - else *fov_y = y; -} /* ======================================================================== @@ -313,4 +264,4 @@ void Matrix4x4_ConcatScale3( matrix4x4 out, float x, float y, float z ) Matrix4x4_Copy( base, out ); Matrix4x4_CreateScale3( temp, x, y, z ); Matrix4x4_Concat( out, base, temp ); -} \ No newline at end of file +} diff --git a/engine/client/gl_rmisc.c b/ref_gl/gl_rmisc.c similarity index 69% rename from engine/client/gl_rmisc.c rename to ref_gl/gl_rmisc.c index 87631756..eff199a9 100644 --- a/engine/client/gl_rmisc.c +++ b/ref_gl/gl_rmisc.c @@ -13,11 +13,10 @@ 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" +#include "screenfade.h" +#include "cdll_int.h" static void R_ParseDetailTextures( const char *filename ) { @@ -29,13 +28,13 @@ static void R_ParseDetailTextures( const char *filename ) texture_t *tex; int i; - afile = FS_LoadFile( filename, NULL, false ); + afile = gEngfuncs.COM_LoadFile( filename, NULL, false ); if( !afile ) return; pfile = afile; // format: 'texturename' 'detailtexture' 'xScale' 'yScale' - while(( pfile = COM_ParseFile( pfile, token )) != NULL ) + while(( pfile = gEngfuncs.COM_ParseFile( pfile, token )) != NULL ) { texname[0] = '\0'; detail_texname[0] = '\0'; @@ -45,26 +44,26 @@ static void R_ParseDetailTextures( const char *filename ) { // NOTE: COM_ParseFile handled some symbols seperately // this code will be fix it - pfile = COM_ParseFile( pfile, token ); + pfile = gEngfuncs.COM_ParseFile( pfile, token ); Q_strncat( texname, "{", sizeof( texname )); Q_strncat( texname, token, sizeof( texname )); } else Q_strncpy( texname, token, sizeof( texname )); // read detailtexture name - pfile = COM_ParseFile( pfile, token ); + pfile = gEngfuncs.COM_ParseFile( pfile, token ); Q_strncat( detail_texname, token, sizeof( detail_texname )); // trying the scales or '{' - pfile = COM_ParseFile( pfile, token ); + pfile = gEngfuncs.COM_ParseFile( pfile, token ); // read second part of detailtexture name if( token[0] == '{' ) { Q_strncat( detail_texname, token, sizeof( detail_texname )); - pfile = COM_ParseFile( pfile, token ); // read scales + pfile = gEngfuncs.COM_ParseFile( pfile, token ); // read scales Q_strncat( detail_texname, token, sizeof( detail_texname )); - pfile = COM_ParseFile( pfile, token ); // parse scales + pfile = gEngfuncs.COM_ParseFile( pfile, token ); // parse scales } Q_snprintf( detail_path, sizeof( detail_path ), "gfx/%s", detail_texname ); @@ -72,16 +71,16 @@ static void R_ParseDetailTextures( const char *filename ) // read scales xScale = Q_atof( token ); - pfile = COM_ParseFile( pfile, token ); + pfile = gEngfuncs.COM_ParseFile( pfile, token ); yScale = Q_atof( token ); if( xScale <= 0.0f || yScale <= 0.0f ) 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; @@ -104,29 +103,6 @@ static void R_ParseDetailTextures( const char *filename ) Mem_Free( afile ); } -/* -======================= -R_ClearStaticEntities - -e.g. by demo request -======================= -*/ -void R_ClearStaticEntities( void ) -{ - int i; - - if( host.type == HOST_DEDICATED ) - return; - - // 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; - - clgame.numStatics = 0; - - CL_ClearEfrags (); -} - void R_NewMap( void ) { texture_t *tx; @@ -134,26 +110,28 @@ void R_NewMap( void ) R_ClearDecals(); // clear all level decals + R_StudioResetPlayerModels(); + // upload detailtextures if( CVAR_TO_BOOL( r_detailtextures )) { 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 ); R_ParseDetailTextures( filepath ); } - if( CVAR_TO_BOOL( v_dark )) + if( gEngfuncs.pfnGetCvarFloat( "v_dark" )) { - screenfade_t *sf = &clgame.fade; + screenfade_t *sf = gEngfuncs.GetScreenFade(); float fadetime = 5.0f; client_textmessage_t *title; - title = CL_TextMessageGet( "GAMETITLE" ); - if( Host_IsQuakeCompatible( )) + title = gEngfuncs.pfnTextMessageGet( "GAMETITLE" ); + if( ENGINE_GET_PARM( PARM_QUAKE_COMPATIBLE )) fadetime = 1.0f; if( title ) @@ -168,27 +146,27 @@ void R_NewMap( void ) sf->fader = sf->fadeg = sf->fadeb = 0; sf->fadealpha = 255; sf->fadeSpeed = (float)sf->fadealpha / sf->fadeReset; - sf->fadeReset += cl.time; + sf->fadeReset += gpGlobals->time; sf->fadeEnd += sf->fadeReset; - Cvar_SetValue( "v_dark", 0.0f ); + gEngfuncs.Cvar_SetValue( "v_dark", 0.0f ); } // 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; @@ -196,8 +174,12 @@ void R_NewMap( void ) tx->texturechain = NULL; } - R_SetupSky( clgame.movevars.skyName ); + R_SetupSky( MOVEVARS->skyName ); GL_BuildLightmaps (); R_GenerateVBO(); + + if( gEngfuncs.drawFuncs->R_NewMap != NULL ) + gEngfuncs.drawFuncs->R_NewMap(); + } diff --git a/ref_gl/gl_rpart.c b/ref_gl/gl_rpart.c new file mode 100644 index 00000000..3d65eedc --- /dev/null +++ b/ref_gl/gl_rpart.c @@ -0,0 +1,299 @@ +/* +cl_part.c - particles and tracers +Copyright (C) 2010 Uncle Mike + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + +#include "gl_local.h" +#include "r_efx.h" +#include "event_flags.h" +#include "entity_types.h" +#include "triangleapi.h" +#include "pm_local.h" +#include "cl_tent.h" +#include "studio.h" + +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 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) +}; + +/* +================ +CL_DrawParticles + +update particle color, position, free expired and draw it +================ +*/ +void CL_DrawParticles( double frametime, particle_t *cl_active_particles, float partsize ) +{ + particle_t *p; + vec3_t right, up; + color24 *pColor; + int alpha; + float size; + + if( !cl_active_particles ) + return; // nothing to draw? + + pglEnable( GL_BLEND ); + pglDisable( GL_ALPHA_TEST ); + pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + + GL_Bind( XASH_TEXTURE0, tr.particleTexture ); + pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + pglDepthMask( GL_FALSE ); + + pglBegin( GL_QUADS ); + + for( p = cl_active_particles; p; p = p->next ) + { + if(( p->type != pt_blob ) || ( p->packedColor == 255 )) + { + size = partsize; // get initial size of particle + + // scale up to keep particles from disappearing + size += (p->org[0] - RI.vieworg[0]) * RI.cull_vforward[0]; + size += (p->org[1] - RI.vieworg[1]) * RI.cull_vforward[1]; + size += (p->org[2] - RI.vieworg[2]) * RI.cull_vforward[2]; + + if( size < 20.0f ) size = partsize; + else size = partsize + size * 0.002f; + + // scale the axes by radius + VectorScale( RI.cull_vright, size, right ); + VectorScale( RI.cull_vup, size, up ); + + p->color = bound( 0, p->color, 255 ); + pColor = gEngfuncs.CL_GetPaletteColor( p->color ); + + alpha = 255 * (p->die - gpGlobals->time) * 16.0f; + if( alpha > 255 || p->type == pt_static ) + alpha = 255; + + pglColor4ub( gEngfuncs.LightToTexGamma( pColor->r ), + gEngfuncs.LightToTexGamma( pColor->g ), + gEngfuncs.LightToTexGamma( pColor->b ), alpha ); + + pglTexCoord2f( 0.0f, 1.0f ); + pglVertex3f( p->org[0] - right[0] + up[0], p->org[1] - right[1] + up[1], p->org[2] - right[2] + up[2] ); + pglTexCoord2f( 0.0f, 0.0f ); + pglVertex3f( p->org[0] + right[0] + up[0], p->org[1] + right[1] + up[1], p->org[2] + right[2] + up[2] ); + pglTexCoord2f( 1.0f, 0.0f ); + pglVertex3f( p->org[0] + right[0] - up[0], p->org[1] + right[1] - up[1], p->org[2] + right[2] - up[2] ); + pglTexCoord2f( 1.0f, 1.0f ); + pglVertex3f( p->org[0] - right[0] - up[0], p->org[1] - right[1] - up[1], p->org[2] - right[2] - up[2] ); + r_stats.c_particle_count++; + } + + gEngfuncs.CL_ThinkParticle( frametime, p ); + } + + pglEnd(); + pglDepthMask( GL_TRUE ); +} + +/* +================ +CL_CullTracer + +check tracer bbox +================ +*/ +static qboolean CL_CullTracer( particle_t *p, const vec3_t start, const vec3_t end ) +{ + vec3_t mins, maxs; + int i; + + // compute the bounding box + for( i = 0; i < 3; i++ ) + { + if( start[i] < end[i] ) + { + mins[i] = start[i]; + maxs[i] = end[i]; + } + else + { + mins[i] = end[i]; + maxs[i] = start[i]; + } + + // don't let it be zero sized + if( mins[i] == maxs[i] ) + { + maxs[i] += gTracerSize[p->type] * 2.0f; + } + } + + // check bbox + return R_CullBox( mins, maxs ); +} + +/* +================ +CL_DrawTracers + +update tracer color, position, free expired and draw it +================ +*/ +void CL_DrawTracers( double frametime, particle_t *cl_active_tracers ) +{ + float scale, atten, gravity; + vec3_t screenLast, screen; + vec3_t start, end, delta; + particle_t *p; + + // update tracer color if this is changed + if( FBitSet( tracerred->flags|tracergreen->flags|tracerblue->flags|traceralpha->flags, FCVAR_CHANGED )) + { + color24 *customColors = &gTracerColors[4]; + customColors->r = (byte)(tracerred->value * traceralpha->value * 255); + customColors->g = (byte)(tracergreen->value * traceralpha->value * 255); + customColors->b = (byte)(tracerblue->value * traceralpha->value * 255); + ClearBits( tracerred->flags, FCVAR_CHANGED ); + ClearBits( tracergreen->flags, FCVAR_CHANGED ); + ClearBits( tracerblue->flags, FCVAR_CHANGED ); + ClearBits( traceralpha->flags, FCVAR_CHANGED ); + } + + if( !cl_active_tracers ) + return; // nothing to draw? + + if( !TriSpriteTexture( gEngfuncs.GetDefaultSprite( REF_DOT_SPRITE ), 0 )) + return; + + pglEnable( GL_BLEND ); + pglBlendFunc( GL_SRC_ALPHA, GL_ONE ); + pglDisable( GL_ALPHA_TEST ); + pglDepthMask( GL_FALSE ); + + gravity = frametime * MOVEVARS->gravity; + scale = 1.0 - (frametime * 0.9); + if( scale < 0.0f ) scale = 0.0f; + + for( p = cl_active_tracers; p; p = p->next ) + { + atten = (p->die - gpGlobals->time); + if( atten > 0.1f ) atten = 0.1f; + + VectorScale( p->vel, ( p->ramp * atten ), delta ); + VectorAdd( p->org, delta, end ); + VectorCopy( p->org, start ); + + if( !CL_CullTracer( p, start, end )) + { + vec3_t verts[4], tmp2; + vec3_t tmp, normal; + color24 *pColor; + + // Transform point into screen space + TriWorldToScreen( start, screen ); + TriWorldToScreen( end, screenLast ); + + // build world-space normal to screen-space direction vector + VectorSubtract( screen, screenLast, tmp ); + + // we don't need Z, we're in screen space + tmp[2] = 0; + VectorNormalize( tmp ); + + // build point along noraml line (normal is -y, x) + VectorScale( RI.cull_vup, tmp[0] * gTracerSize[p->type], normal ); + VectorScale( RI.cull_vright, -tmp[1] * gTracerSize[p->type], tmp2 ); + VectorSubtract( normal, tmp2, normal ); + + // compute four vertexes + VectorSubtract( start, normal, verts[0] ); + VectorAdd( start, normal, verts[1] ); + VectorAdd( verts[0], delta, verts[2] ); + VectorAdd( verts[1], delta, verts[3] ); + + if( p->color > sizeof( gTracerColors ) / sizeof( color24 ) ) + { + gEngfuncs.Con_Printf( S_ERROR "UserTracer with color > %d\n", sizeof( gTracerColors ) / sizeof( color24 )); + p->color = 0; + } + + pColor = &gTracerColors[p->color]; + pglColor4ub( pColor->r, pColor->g, pColor->b, p->packedColor ); + + pglBegin( GL_QUADS ); + pglTexCoord2f( 0.0f, 0.8f ); + pglVertex3fv( verts[2] ); + pglTexCoord2f( 1.0f, 0.8f ); + pglVertex3fv( verts[3] ); + pglTexCoord2f( 1.0f, 0.0f ); + pglVertex3fv( verts[1] ); + pglTexCoord2f( 0.0f, 0.0f ); + pglVertex3fv( verts[0] ); + pglEnd(); + } + + // evaluate position + VectorMA( p->org, frametime, p->vel, p->org ); + + if( p->type == pt_grav ) + { + p->vel[0] *= scale; + p->vel[1] *= scale; + p->vel[2] -= gravity; + + p->packedColor = 255 * (p->die - gpGlobals->time) * 2; + if( p->packedColor > 255 ) p->packedColor = 255; + } + else if( p->type == pt_slowgrav ) + { + p->vel[2] = gravity * 0.05; + } + } + + pglDepthMask( GL_TRUE ); +} + +/* +=============== +CL_DrawParticlesExternal + +allow to draw effects from custom renderer +=============== +*/ +void CL_DrawParticlesExternal( const ref_viewpass_t *rvp, qboolean trans_pass, float frametime ) +{ + ref_instance_t oldRI = RI; + + memcpy( &oldRI, &RI, sizeof( ref_instance_t )); + R_SetupRefParams( rvp ); + R_SetupFrustum(); + R_SetupGL( false ); // don't touch GL-states + + // setup PVS for frame + memcpy( RI.visbytes, tr.visbytes, gpGlobals->visbytes ); + tr.frametime = frametime; + + gEngfuncs.CL_DrawEFX( frametime, trans_pass ); + + // restore internal state + memcpy( &RI, &oldRI, sizeof( ref_instance_t )); +} diff --git a/engine/client/gl_rsurf.c b/ref_gl/gl_rsurf.c similarity index 92% rename from engine/client/gl_rsurf.c rename to ref_gl/gl_rsurf.c index f3358346..8819ac75 100644 --- a/engine/client/gl_rsurf.c +++ b/ref_gl/gl_rsurf.c @@ -13,11 +13,9 @@ 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" +#include "mod_local.h" typedef struct { @@ -47,16 +45,16 @@ static void R_DrawVBO( qboolean drawlightmaps, qboolean drawtextures ); byte *Mod_GetCurrentVis( void ) { - if( clgame.drawFuncs.Mod_GetCurrentVis && tr.fCustomRendering ) - return clgame.drawFuncs.Mod_GetCurrentVis(); + if( gEngfuncs.drawFuncs->Mod_GetCurrentVis && tr.fCustomRendering ) + return gEngfuncs.drawFuncs->Mod_GetCurrentVis(); return RI.visbytes; } -void Mod_SetOrthoBounds( float *mins, float *maxs ) +void Mod_SetOrthoBounds( const float *mins, const float *maxs ) { - if( clgame.drawFuncs.GL_OrthoBounds ) + if( gEngfuncs.drawFuncs->GL_OrthoBounds ) { - clgame.drawFuncs.GL_OrthoBounds( mins, maxs ); + gEngfuncs.drawFuncs->GL_OrthoBounds( mins, maxs ); } Vector2Average( maxs, mins, world_orthocenter ); @@ -90,11 +88,12 @@ static void SubdividePolygon_r( msurface_t *warpface, int numverts, float *verts float sample_size; vec3_t mins, maxs; glpoly_t *poly; + model_t *loadmodel = gEngfuncs.Mod_GetCurrentLoadingModel(); if( numverts > ( SUBDIVIDE_SIZE - 4 )) - Host_Error( "Mod_SubdividePolygon: too many vertexes on face ( %i )\n", numverts ); + gEngfuncs.Host_Error( "Mod_SubdividePolygon: too many vertexes on face ( %i )\n", numverts ); - sample_size = Mod_SampleSizeForFace( warpface ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( warpface ); BoundPoly( numverts, verts, mins, maxs ); for( i = 0; i < 3; i++ ) @@ -245,6 +244,7 @@ void GL_SubdivideSurface( msurface_t *fa ) int numverts; int i, lindex; float *vec; + model_t *loadmodel = gEngfuncs.Mod_GetCurrentLoadingModel(); // convert edges back to a normal polygon numverts = 0; @@ -295,7 +295,7 @@ void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa ) glt->srcHeight = tex->height; } - sample_size = Mod_SampleSizeForFace( fa ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( fa ); // reconstruct the polygon pedges = mod->edges; @@ -427,7 +427,7 @@ texture_t *R_TextureAnim( texture_t *b ) speed = 10; else speed = 20; - reletive = (int)(cl.time * speed) % base->anim_total; + reletive = (int)(gpGlobals->time * speed) % base->anim_total; } @@ -481,7 +481,7 @@ texture_t *R_TextureAnimation( msurface_t *s ) speed = 10; else speed = 20; - reletive = (int)(cl.time * speed) % base->anim_total; + reletive = (int)(gpGlobals->time * speed) % base->anim_total; } count = 0; @@ -518,7 +518,7 @@ void R_AddDynamicLights( msurface_t *surf ) // no dlighted surfaces here if( !R_CountSurfaceDlights( surf )) return; - sample_size = Mod_SampleSizeForFace( surf ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( surf ); smax = (info->lightextents[0] / sample_size) + 1; tmax = (info->lightextents[1] / sample_size) + 1; tex = surf->texinfo; @@ -537,7 +537,7 @@ void R_AddDynamicLights( msurface_t *surf ) if( !FBitSet( surf->dlightbits, BIT( lnum ))) continue; // not lit by this light - dl = &cl_dlights[lnum]; + dl = gEngfuncs.GetDynamicLight( lnum ); // transform light origin to local bmodel space if( !tr.modelviewIdentity ) @@ -581,9 +581,9 @@ void R_AddDynamicLights( msurface_t *surf ) if( dist < minlight ) { - bl[0] += ((int)((rad - dist) * 256) * LightToTexGamma( dl->color.r )) / 256; - bl[1] += ((int)((rad - dist) * 256) * LightToTexGamma( dl->color.g )) / 256; - bl[2] += ((int)((rad - dist) * 256) * LightToTexGamma( dl->color.b )) / 256; + bl[0] += ((int)((rad - dist) * 256) * gEngfuncs.LightToTexGamma( dl->color.r )) / 256; + bl[1] += ((int)((rad - dist) * 256) * gEngfuncs.LightToTexGamma( dl->color.g )) / 256; + bl[2] += ((int)((rad - dist) * 256) * gEngfuncs.LightToTexGamma( dl->color.b )) / 256; } } } @@ -703,7 +703,7 @@ static void LM_UploadBlock( qboolean dynamic ) tr.lightmapTextures[i] = GL_LoadTextureInternal( lmName, &r_lightmap, TF_FONT|TF_ATLAS_PAGE ); if( ++gl_lms.current_lightmap_texture == MAX_LIGHTMAPS ) - Host_Error( "AllocBlock: full\n" ); + gEngfuncs.Host_Error( "AllocBlock: full\n" ); } } @@ -724,7 +724,7 @@ static void R_BuildLightMap( msurface_t *surf, byte *dest, int stride, qboolean mextrasurf_t *info = surf->info; color24 *lm; - sample_size = Mod_SampleSizeForFace( surf ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( surf ); smax = ( info->lightextents[0] / sample_size ) + 1; tmax = ( info->lightextents[1] / sample_size ) + 1; size = smax * tmax; @@ -740,9 +740,9 @@ static void R_BuildLightMap( msurface_t *surf, byte *dest, int stride, qboolean for( i = 0, bl = r_blocklights; i < size; i++, bl += 3, lm++ ) { - bl[0] += LightToTexGamma( lm->r ) * scale; - bl[1] += LightToTexGamma( lm->g ) * scale; - bl[2] += LightToTexGamma( lm->b ) * scale; + bl[0] += gEngfuncs.LightToTexGamma( lm->r ) * scale; + bl[1] += gEngfuncs.LightToTexGamma( lm->g ) * scale; + bl[2] += gEngfuncs.LightToTexGamma( lm->b ) * scale; } } @@ -793,7 +793,7 @@ void DrawGLPoly( glpoly_t *p, float xScale, float yScale ) float flRate, flAngle; gl_texture_t *texture; - if( Host_IsQuakeCompatible() && RI.currententity == clgame.entities ) + if( ENGINE_GET_PARM( PARM_QUAKE_COMPATIBLE ) && RI.currententity == gEngfuncs.GetEntityByIndex( 0 ) ) { // same as doom speed flConveyorSpeed = -35.0f; @@ -809,8 +809,8 @@ void DrawGLPoly( glpoly_t *p, float xScale, float yScale ) flAngle = ( flConveyorSpeed >= 0 ) ? 180 : 0; SinCos( flAngle * ( M_PI / 180.0f ), &sy, &cy ); - sOffset = cl.time * cy * flRate; - tOffset = cl.time * sy * flRate; + sOffset = gpGlobals->time * cy * flRate; + tOffset = gpGlobals->time * sy * flRate; // make sure that we are positive if( sOffset < 0.0f ) sOffset += 1.0f + -(int)sOffset; @@ -879,7 +879,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 ) @@ -957,7 +957,7 @@ void R_BlendLightmaps( void ) mextrasurf_t *info = surf->info; byte *base; - sample_size = Mod_SampleSizeForFace( surf ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( surf ); smax = ( info->lightextents[0] / sample_size ) + 1; tmax = ( info->lightextents[1] / sample_size ) + 1; @@ -993,7 +993,7 @@ void R_BlendLightmaps( void ) // try uploading the block now if( !LM_AllocBlock( smax, tmax, &surf->info->dlight_s, &surf->info->dlight_t )) - Host_Error( "AllocBlock: full\n" ); + gEngfuncs.Host_Error( "AllocBlock: full\n" ); base = gl_lms.lightmap_buffer; base += ( surf->info->dlight_t * BLOCK_SIZE + surf->info->dlight_s ) * 4; @@ -1223,7 +1223,7 @@ dynamic: int sample_size; int smax, tmax; - sample_size = Mod_SampleSizeForFace( fa ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( fa ); smax = ( info->lightextents[0] / sample_size ) + 1; tmax = ( info->lightextents[1] / sample_size ) + 1; @@ -1269,10 +1269,10 @@ void R_DrawTextureChains( void ) GL_SetupFogColorForSurfaces(); // restore worldmodel - RI.currententity = clgame.entities; + RI.currententity = gEngfuncs.GetEntityByIndex( 0 ); RI.currentmodel = RI.currententity->model; - if( FBitSet( world.flags, FWORLD_SKYSPHERE ) && !FBitSet( world.flags, FWORLD_CUSTOM_SKYBOX )) + if( ENGINE_GET_PARM( PARM_SKY_SPHERE ) ) { pglDisable( GL_TEXTURE_2D ); pglColor3f( 1.0f, 1.0f, 1.0f ); @@ -1282,7 +1282,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( ENGINE_GET_PARM( PARM_SKY_SPHERE ) ) { pglEnable( GL_TEXTURE_2D ); if( skychain ) @@ -1290,9 +1290,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,14 +1300,14 @@ 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 )) + if( ENGINE_GET_PARM( PARM_QUAKE_COMPATIBLE ) && FBitSet( s->flags, SURF_TRANSPARENT )) { draw_alpha_surfaces = true; continue; // draw transparent surfaces later - } + } for( ; s != NULL; s = s->texturechain ) R_RenderBrushPoly( s, CULL_VISIBLE ); @@ -1343,14 +1343,14 @@ void R_DrawAlphaTextureChains( void ) GL_SetupFogColorForSurfaces(); // restore worldmodel - RI.currententity = clgame.entities; + RI.currententity = gEngfuncs.GetEntityByIndex( 0 ); RI.currentmodel = RI.currententity->model; 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,11 +1384,11 @@ 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 - RI.currententity = clgame.entities; + RI.currententity = gEngfuncs.GetEntityByIndex( 0 ); RI.currentmodel = RI.currententity->model; // go back to the world matrix @@ -1399,11 +1399,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; @@ -1483,7 +1483,7 @@ void R_SetRenderMode( cl_entity_t *e ) case kRenderTransAlpha: pglEnable( GL_ALPHA_TEST ); pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - if( Host_IsQuakeCompatible( )) + if( ENGINE_GET_PARM( PARM_QUAKE_COMPATIBLE )) { pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); pglColor4f( 1.0f, 1.0f, 1.0f, tr.blend ); @@ -1529,7 +1529,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 )) @@ -1558,7 +1558,7 @@ void R_DrawBrushModel( cl_entity_t *e ) if( rotated ) R_RotateForEntity( e ); else R_TranslateForEntity( e ); - if( Host_IsQuakeCompatible() && FBitSet( clmodel->flags, MODEL_TRANSPARENT )) + if( ENGINE_GET_PARM( PARM_QUAKE_COMPATIBLE ) && FBitSet( clmodel->flags, MODEL_TRANSPARENT )) e->curstate.rendermode = kRenderTransAlpha; e->visframe = tr.realframecount; // visible @@ -1567,9 +1567,11 @@ void R_DrawBrushModel( cl_entity_t *e ) else VectorSubtract( RI.cullorigin, e->origin, tr.modelorg ); // calculate dynamic lighting for bmodel - for( k = 0, l = cl_dlights; k < MAX_DLIGHTS; k++, l++ ) + for( k = 0; k < MAX_DLIGHTS; k++ ) { - if( l->die < cl.time || !l->radius ) + l = gEngfuncs.GetDynamicLight( k ); + + if( l->die < gpGlobals->time || !l->radius ) continue; VectorCopy( l->origin, oldorigin ); // save lightorigin @@ -1597,7 +1599,7 @@ void R_DrawBrushModel( cl_entity_t *e ) for( i = 0; i < clmodel->nummodelsurfaces; i++, psurf++ ) { - if( FBitSet( psurf->flags, SURF_DRAWTURB ) && !Host_IsQuakeCompatible( )) + if( FBitSet( psurf->flags, SURF_DRAWTURB ) && !ENGINE_GET_PARM( PARM_QUAKE_COMPATIBLE )) { if( psurf->plane->type != PLANE_Z && !FBitSet( e->curstate.effects, EF_WATERSIDES )) continue; @@ -1616,22 +1618,22 @@ void R_DrawBrushModel( cl_entity_t *e ) continue; } - if( num_sorted < world.max_surfaces ) + if( num_sorted < gpGlobals->max_surfaces ) { - world.draw_surfaces[num_sorted].surf = psurf; - world.draw_surfaces[num_sorted].cull = cull_type; + gpGlobals->draw_surfaces[num_sorted].surf = psurf; + gpGlobals->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( gpGlobals->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( gpGlobals->draw_surfaces[i].surf, true ) ) + R_RenderBrushPoly( gpGlobals->draw_surfaces[i].surf, gpGlobals->draw_surfaces[i].cull ); R_DrawVBO( R_HasLightmap(), true ); if( e->curstate.rendermode == kRenderTransColor ) @@ -1781,7 +1783,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; @@ -1792,7 +1794,7 @@ void R_GenerateVBO() // we do not want to write vbo code that does not use multitexture if( !GL_Support( GL_ARB_VERTEX_BUFFER_OBJECT_EXT ) || !GL_Support( GL_ARB_MULTITEXTURE ) || glConfig.max_texture_units < 2 ) { - Cvar_FullSet( "r_vbo", "0", FCVAR_READ_ONLY ); + gEngfuncs.Cvar_FullSet( "r_vbo", "0", FCVAR_READ_ONLY ); return; } @@ -1812,7 +1814,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 ); @@ -1827,9 +1829,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; @@ -1837,14 +1839,14 @@ 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 ) { // generate new array and new vbotexture node vbo->array = Mem_Calloc( vbos.mempool, sizeof( vbovertex_t ) * vbo->array_len ); - Msg( "R_GenerateVBOs: allocated array of %d verts, texture %d\n", vbo->array_len, j ); + gEngfuncs.Con_Printf( "R_GenerateVBOs: allocated array of %d verts, texture %d\n", vbo->array_len, j ); vbo->next = Mem_Calloc( vbos.mempool, sizeof( vboarray_t ) ); vbo = vbo->next; vbotex->next = Mem_Calloc( vbos.mempool, sizeof( vbotexture_t ) ); @@ -1872,7 +1874,7 @@ void R_GenerateVBO() // allocate last array vbo->array = Mem_Calloc( vbos.mempool, sizeof( vbovertex_t ) * vbo->array_len ); - Msg( "R_GenerateVBOs: allocated array of %d verts\n", vbo->array_len ); + gEngfuncs.Con_Printf( "R_GenerateVBOs: allocated array of %d verts\n", vbo->array_len ); // switch to list begin vbo = vbos.arraylist; @@ -1894,9 +1896,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 ) ) @@ -1905,7 +1907,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 @@ -1941,9 +1943,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; } @@ -2168,7 +2170,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 ) { @@ -2313,14 +2315,14 @@ 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; int sample_size; info = surf->info; - sample_size = Mod_SampleSizeForFace( surf ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( surf ); smax = ( info->lightextents[0] / sample_size ) + 1; tmax = ( info->lightextents[1] / sample_size ) + 1; @@ -2438,7 +2440,7 @@ static void R_DrawLightmappedVBO( vboarray_t *vbo, vbotexture_t *vbotex, texture // try upload the block now if( !LM_AllocBlock( smax, tmax, &info->dlight_s, &info->dlight_t )) - Host_Error( "AllocBlock: full\n" ); + gEngfuncs.Host_Error( "AllocBlock: full\n" ); base = gl_lms.lightmap_buffer; base += ( info->dlight_t * BLOCK_SIZE + info->dlight_s ) * 4; @@ -2629,7 +2631,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; @@ -2920,7 +2922,7 @@ static qboolean R_CheckLightMap( msurface_t *fa ) mextrasurf_t *info; info = fa->info; - sample_size = Mod_SampleSizeForFace( fa ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( fa ); smax = ( info->lightextents[0] / sample_size ) + 1; tmax = ( info->lightextents[1] / sample_size ) + 1; @@ -2961,10 +2963,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; @@ -2980,7 +2982,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 ) ) { @@ -3073,7 +3075,7 @@ loc0: // deal with model fragments in this leaf if( pleaf->efrags ) - R_StoreEfrags( &pleaf->efrags, tr.realframecount ); + gEngfuncs.R_StoreEfrags( &pleaf->efrags, tr.realframecount ); r_stats.c_world_leafs++; return; @@ -3089,7 +3091,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; @@ -3167,7 +3169,7 @@ static void R_DrawTopViewLeaf( mleaf_t *pleaf, uint clipflags ) // deal with model fragments in this leaf if( pleaf->efrags ) - R_StoreEfrags( &pleaf->efrags, tr.realframecount ); + gEngfuncs.R_StoreEfrags( &pleaf->efrags, tr.realframecount ); r_stats.c_world_leafs++; } @@ -3217,7 +3219,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 ) @@ -3310,7 +3312,7 @@ void R_DrawWorld( void ) // paranoia issues: when gl_renderer is "0" we need have something valid for currententity // to prevent crashing until HeadShield drawing. - RI.currententity = clgame.entities; + RI.currententity = gEngfuncs.GetEntityByIndex( 0 ); RI.currentmodel = RI.currententity->model; if( !RI.drawWorld || RI.onlyClientDraw ) @@ -3328,20 +3330,20 @@ void R_DrawWorld( void ) R_ClearSkyBox (); - start = Sys_DoubleTime(); + start = gEngfuncs.pfnTime(); if( RI.drawOrtho ) - R_DrawWorldTopView( cl.worldmodel->nodes, RI.frustum.clipFlags ); - else R_RecursiveWorldNode( cl.worldmodel->nodes, RI.frustum.clipFlags ); - end = Sys_DoubleTime(); + R_DrawWorldTopView( WORLDMODEL->nodes, RI.frustum.clipFlags ); + else R_RecursiveWorldNode( WORLDMODEL->nodes, RI.frustum.clipFlags ); + end = gEngfuncs.pfnTime(); r_stats.t_world_node = end - start; - start = Sys_DoubleTime(); - R_DrawVBO( !CVAR_TO_BOOL(r_fullbright) && !!cl.worldmodel->lightdata, true ); + start = gEngfuncs.pfnTime(); + R_DrawVBO( !CVAR_TO_BOOL(r_fullbright) && !!WORLDMODEL->lightdata, true ); R_DrawTextureChains(); - if( !CL_IsDevOverviewMode( )) + if( !ENGINE_GET_PARM( PARM_DEV_OVERVIEW )) { DrawDecalsBatch(); GL_ResetFogColor(); @@ -3353,7 +3355,7 @@ void R_DrawWorld( void ) R_DrawSkyBox(); } - end = Sys_DoubleTime(); + end = gEngfuncs.pfnTime(); r_stats.t_world_draw = end - start; tr.num_draw_decals = 0; @@ -3398,12 +3400,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 = gEngfuncs.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 = gEngfuncs.Mod_PointInLeaf( test, WORLDMODEL->nodes ); } if(( leaf->contents != CONTENTS_SOLID ) && ( RI.viewleaf != leaf )) @@ -3420,17 +3422,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 ); + gEngfuncs.R_FatPVS( RI.pvsorigin, REFPVS_RADIUS, RI.visbytes, FBitSet( RI.params, RP_OLDVIEWLEAF ), novis ); + if( force && !novis ) gEngfuncs.R_FatPVS( test, REFPVS_RADIUS, RI.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 ) @@ -3453,6 +3455,7 @@ void GL_CreateSurfaceLightmap( msurface_t *surf ) int sample_size; mextrasurf_t *info = surf->info; byte *base; + model_t *loadmodel = gEngfuncs.Mod_GetCurrentLoadingModel(); if( !loadmodel->lightdata ) return; @@ -3460,7 +3463,7 @@ void GL_CreateSurfaceLightmap( msurface_t *surf ) if( FBitSet( surf->flags, SURF_DRAWTILED )) return; - sample_size = Mod_SampleSizeForFace( surf ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( surf ); smax = ( info->lightextents[0] / sample_size ) + 1; tmax = ( info->lightextents[1] / sample_size ) + 1; @@ -3470,7 +3473,7 @@ void GL_CreateSurfaceLightmap( msurface_t *surf ) LM_InitBlock(); if( !LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t )) - Host_Error( "AllocBlock: full\n" ); + gEngfuncs.Host_Error( "AllocBlock: full\n" ); } surf->lightmaptexturenum = gl_lms.current_lightmap_texture; @@ -3495,7 +3498,7 @@ void GL_RebuildLightmaps( void ) int i, j; model_t *m; - if( !cl.video_prepped ) + if( !ENGINE_GET_PARM( PARM_CLIENT_ACTIVE ) ) return; // wait for worldmodel ClearBits( vid_brightness->flags, FCVAR_CHANGED ); @@ -3516,25 +3519,25 @@ void GL_RebuildLightmaps( void ) LM_InitBlock(); - for( i = 0; i < cl.nummodels; i++ ) + for( i = 0; i < ENGINE_GET_PARM( PARM_NUMMODELS ); i++ ) { - if(( m = CL_ModelHandle( i + 1 )) == NULL ) + if(( m = gEngfuncs.pfnGetModelByIndex( i + 1 )) == NULL ) continue; if( m->name[0] == '*' || m->type != mod_brush ) continue; - loadmodel = m; + gEngfuncs.Mod_SetCurrentLoadingModel( m ); for( j = 0; j < m->numsurfaces; j++ ) GL_CreateSurfaceLightmap( m->surfaces + j ); } LM_UploadBlock( false ); - if( clgame.drawFuncs.GL_BuildLightmaps ) + if( gEngfuncs.drawFuncs->GL_BuildLightmaps ) { // build lightmaps on the client-side - clgame.drawFuncs.GL_BuildLightmaps( ); + gEngfuncs.drawFuncs->GL_BuildLightmaps( ); } } @@ -3562,7 +3565,7 @@ void GL_BuildLightmaps( void ) memset( &RI, 0, sizeof( RI )); // update the lightmap blocksize - if( FBitSet( host.features, ENGINE_LARGE_LIGHTMAPS )) + if( FBitSet( ENGINE_GET_PARM( PARM_FEATURES ), ENGINE_LARGE_LIGHTMAPS )) tr.block_size = BLOCK_SIZE_MAX; else tr.block_size = BLOCK_SIZE_DEFAULT; @@ -3582,9 +3585,9 @@ void GL_BuildLightmaps( void ) LM_InitBlock(); - for( i = 0; i < cl.nummodels; i++ ) + for( i = 0; i < ENGINE_GET_PARM( PARM_NUMMODELS ); i++ ) { - if(( m = CL_ModelHandle( i + 1 )) == NULL ) + if(( m = gEngfuncs.pfnGetModelByIndex( i + 1 )) == NULL ) continue; if( m->name[0] == '*' || m->type != mod_brush ) @@ -3595,7 +3598,7 @@ void GL_BuildLightmaps( void ) // clearing all decal chains m->surfaces[j].pdecals = NULL; m->surfaces[j].visframe = 0; - loadmodel = m; + gEngfuncs.Mod_SetCurrentLoadingModel( m ); GL_CreateSurfaceLightmap( m->surfaces + j ); @@ -3614,10 +3617,10 @@ void GL_BuildLightmaps( void ) LM_UploadBlock( false ); - if( clgame.drawFuncs.GL_BuildLightmaps ) + if( gEngfuncs.drawFuncs->GL_BuildLightmaps ) { // build lightmaps on the client-side - clgame.drawFuncs.GL_BuildLightmaps( ); + gEngfuncs.drawFuncs->GL_BuildLightmaps( ); } // now gamma and brightness are valid @@ -3630,15 +3633,15 @@ void GL_InitRandomTable( void ) int tu, tv; // make random predictable - COM_SetRandomSeed( 255 ); + gEngfuncs.COM_SetRandomSeed( 255 ); for( tu = 0; tu < MOD_FRAMES; tu++ ) { for( tv = 0; tv < MOD_FRAMES; tv++ ) { - rtable[tu][tv] = COM_RandomLong( 0, 0x7FFF ); + rtable[tu][tv] = gEngfuncs.COM_RandomLong( 0, 0x7FFF ); } } - COM_SetRandomSeed( 0 ); + gEngfuncs.COM_SetRandomSeed( 0 ); } diff --git a/engine/client/gl_sprite.c b/ref_gl/gl_sprite.c similarity index 81% rename from engine/client/gl_sprite.c rename to ref_gl/gl_sprite.c index b98a3a2c..496f4ac2 100644 --- a/engine/client/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" @@ -26,8 +24,8 @@ GNU General Public License for more details. #define MAPSPRITE_SIZE 128 #define GLARE_FALLOFF 19000.0f -convar_t *r_sprite_lerping; -convar_t *r_sprite_lighting; +cvar_t *r_sprite_lerping; +cvar_t *r_sprite_lighting; char sprite_name[MAX_QPATH]; char group_suffix[8]; static uint r_texFlags = 0; @@ -42,8 +40,8 @@ R_SpriteInit */ void R_SpriteInit( void ) { - r_sprite_lerping = Cvar_Get( "r_sprite_lerping", "1", FCVAR_ARCHIVE, "enables sprite animation lerping" ); - r_sprite_lighting = Cvar_Get( "r_sprite_lighting", "1", FCVAR_ARCHIVE, "enables sprite lighting (blood etc)" ); + r_sprite_lerping = gEngfuncs.Cvar_Get( "r_sprite_lerping", "1", FCVAR_ARCHIVE, "enables sprite animation lerping" ); + r_sprite_lighting = gEngfuncs.Cvar_Get( "r_sprite_lighting", "1", FCVAR_ARCHIVE, "enables sprite lighting (blood etc)" ); } /* @@ -146,89 +144,22 @@ load sprite model */ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags ) { - dsprite_q1_t *pinq1; - dsprite_hl_t *pinhl; - dsprite_t *pin; - short *numi = NULL; - dframetype_t *pframetype; + const dsprite_t *pin; + const short *numi = NULL; + const dframetype_t *pframetype; msprite_t *psprite; - int i, size; + int i; - if( loaded ) *loaded = false; - pin = (dsprite_t *)buffer; - mod->type = mod_sprite; - r_texFlags = texFlags; - i = pin->version; + pin = buffer; + psprite = mod->cache.data; - if( pin->ident != IDSPRITEHEADER ) - { - Con_DPrintf( S_ERROR "%s has wrong id (%x should be %x)\n", mod->name, pin->ident, IDSPRITEHEADER ); - return; - } - - if( i != SPRITE_VERSION_Q1 && i != SPRITE_VERSION_HL && i != SPRITE_VERSION_32 ) - { - Con_DPrintf( S_ERROR "%s has wrong version number (%i should be %i or %i)\n", mod->name, i, SPRITE_VERSION_Q1, SPRITE_VERSION_HL ); - return; - } - - mod->mempool = Mem_AllocPool( va( "^2%s^7", mod->name )); - sprite_version = i; - - if( i == SPRITE_VERSION_Q1 || i == SPRITE_VERSION_32 ) - { - pinq1 = (dsprite_q1_t *)buffer; - size = sizeof( msprite_t ) + ( pinq1->numframes - 1 ) * sizeof( psprite->frames ); - psprite = Mem_Calloc( mod->mempool, size ); - mod->cache.data = psprite; // make link to extradata - - psprite->type = pinq1->type; - psprite->texFormat = SPR_ADDITIVE; //SPR_ALPHTEST; - psprite->numframes = mod->numframes = pinq1->numframes; - psprite->facecull = SPR_CULL_FRONT; - psprite->radius = pinq1->boundingradius; - psprite->synctype = pinq1->synctype; - - // LordHavoc: hack to allow sprites to be non-fullbright - for( i = 0; i < MAX_QPATH && mod->name[i]; i++ ) - if( mod->name[i] == '!' ) - psprite->texFormat = SPR_ALPHTEST; - - mod->mins[0] = mod->mins[1] = -pinq1->bounds[0] * 0.5f; - mod->maxs[0] = mod->maxs[1] = pinq1->bounds[0] * 0.5f; - mod->mins[2] = -pinq1->bounds[1] * 0.5f; - mod->maxs[2] = pinq1->bounds[1] * 0.5f; + if( pin->version == SPRITE_VERSION_Q1 || pin->version == SPRITE_VERSION_32 ) numi = NULL; - } - else if( i == SPRITE_VERSION_HL ) - { - pinhl = (dsprite_hl_t *)buffer; - size = sizeof( msprite_t ) + ( pinhl->numframes - 1 ) * sizeof( psprite->frames ); - psprite = Mem_Calloc( mod->mempool, size ); - mod->cache.data = psprite; // make link to extradata - - psprite->type = pinhl->type; - psprite->texFormat = pinhl->texFormat; - psprite->numframes = mod->numframes = pinhl->numframes; - psprite->facecull = pinhl->facetype; - psprite->radius = pinhl->boundingradius; - psprite->synctype = pinhl->synctype; - - mod->mins[0] = mod->mins[1] = -pinhl->bounds[0] * 0.5f; - mod->maxs[0] = mod->maxs[1] = pinhl->bounds[0] * 0.5f; - mod->mins[2] = -pinhl->bounds[1] * 0.5f; - mod->maxs[2] = pinhl->bounds[1] * 0.5f; - numi = (short *)(pinhl + 1); - } - - if( host.type == HOST_DEDICATED ) - { - // skip frames loading - if( loaded ) *loaded = true; // done - psprite->numframes = 0; - return; - } + else if( pin->version == SPRITE_VERSION_HL ) + numi = (const short *)((const byte*)buffer + sizeof( dsprite_hl_t )); + r_texFlags = texFlags; + sprite_version = pin->version; Q_strncpy( sprite_name, mod->name, sizeof( sprite_name )); COM_StripExtension( sprite_name ); @@ -236,35 +167,35 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui { rgbdata_t *pal; - pal = FS_LoadImage( "#id.pal", (byte *)&i, 768 ); - pframetype = (dframetype_t *)(pinq1 + 1); - FS_FreeImage( pal ); // palette installed, no reason to keep this data + pal = gEngfuncs.FS_LoadImage( "#id.pal", (byte *)&i, 768 ); + pframetype = (const dframetype_t *)((const byte*)buffer + sizeof( dsprite_q1_t )); // pinq1 + 1 + gEngfuncs.FS_FreeImage( pal ); // palette installed, no reason to keep this data } else if( *numi == 256 ) - { - byte *src = (byte *)(numi+1); + { + const byte *src = (const byte *)(numi+1); rgbdata_t *pal; - + // install palette switch( psprite->texFormat ) { case SPR_INDEXALPHA: - pal = FS_LoadImage( "#gradient.pal", src, 768 ); + pal = gEngfuncs.FS_LoadImage( "#gradient.pal", src, 768 ); + break; + case SPR_ALPHTEST: + pal = gEngfuncs.FS_LoadImage( "#masked.pal", src, 768 ); break; - case SPR_ALPHTEST: - pal = FS_LoadImage( "#masked.pal", src, 768 ); - break; default: - pal = FS_LoadImage( "#normal.pal", src, 768 ); + pal = gEngfuncs.FS_LoadImage( "#normal.pal", src, 768 ); break; } - pframetype = (dframetype_t *)(src + 768); - FS_FreeImage( pal ); // palette installed, no reason to keep this data + pframetype = (const dframetype_t *)(src + 768); + gEngfuncs.FS_FreeImage( pal ); // palette installed, no reason to keep this data } else { - Con_DPrintf( S_ERROR "%s has wrong number of palette colors %i (should be 256)\n", mod->name, *numi ); + gEngfuncs.Con_DPrintf( S_ERROR "%s has wrong number of palette colors %i (should be 256)\n", mod->name, *numi ); return; } @@ -318,9 +249,9 @@ void Mod_LoadMapSprite( model_t *mod, const void *buffer, size_t size, qboolean if( loaded ) *loaded = false; Q_snprintf( texname, sizeof( texname ), "#%s", mod->name ); - Image_SetForceFlags( IL_OVERVIEW ); - pix = FS_LoadImage( texname, buffer, size ); - Image_ClearForceFlags(); + gEngfuncs.Image_SetForceFlags( IL_OVERVIEW ); + pix = gEngfuncs.FS_LoadImage( texname, buffer, size ); + gEngfuncs.Image_ClearForceFlags(); if( !pix ) return; // bad image or something else mod->type = mod_sprite; @@ -338,7 +269,7 @@ void Mod_LoadMapSprite( model_t *mod, const void *buffer, size_t size, qboolean if( h < MAPSPRITE_SIZE ) h = MAPSPRITE_SIZE; // resample image if needed - Image_Process( &pix, w, h, IMAGE_FORCE_RGBA|IMAGE_RESAMPLE, 0.0f ); + gEngfuncs.Image_Process( &pix, w, h, IMAGE_FORCE_RGBA|IMAGE_RESAMPLE, 0.0f ); w = h = MAPSPRITE_SIZE; @@ -367,8 +298,8 @@ void Mod_LoadMapSprite( model_t *mod, const void *buffer, size_t size, qboolean temp.width = w; temp.height = h; temp.type = pix->type; - temp.flags = pix->flags; - temp.size = w * h * PFDesc[temp.type].bpp; + temp.flags = pix->flags; + temp.size = w * h * gEngfuncs.Image_GetPFDesc(temp.type)->bpp; temp.buffer = Mem_Malloc( r_temppool, temp.size ); temp.palette = NULL; @@ -412,7 +343,7 @@ void Mod_LoadMapSprite( model_t *mod, const void *buffer, size_t size, qboolean } } - FS_FreeImage( pix ); + gEngfuncs.FS_FreeImage( pix ); Mem_Free( temp.buffer ); if( loaded ) *loaded = true; @@ -425,48 +356,37 @@ Mod_UnloadSpriteModel release sprite model and frames ==================== */ -void Mod_UnloadSpriteModel( model_t *mod ) +void Mod_SpriteUnloadTextures( void *data ) { msprite_t *psprite; mspritegroup_t *pspritegroup; mspriteframe_t *pspriteframe; int i, j; - Assert( mod != NULL ); + psprite = data; - if( mod->type == mod_sprite ) + if( psprite ) { - if( host.type != HOST_DEDICATED ) + // release all textures + for( i = 0; i < psprite->numframes; i++ ) { - psprite = mod->cache.data; - - if( psprite ) + if( psprite->frames[i].type == SPR_SINGLE ) { - // release all textures - for( i = 0; i < psprite->numframes; i++ ) - { - if( psprite->frames[i].type == SPR_SINGLE ) - { - pspriteframe = psprite->frames[i].frameptr; - GL_FreeTexture( pspriteframe->gl_texturenum ); - } - else - { - pspritegroup = (mspritegroup_t *)psprite->frames[i].frameptr; + pspriteframe = psprite->frames[i].frameptr; + GL_FreeTexture( pspriteframe->gl_texturenum ); + } + else + { + pspritegroup = (mspritegroup_t *)psprite->frames[i].frameptr; - for( j = 0; j < pspritegroup->numframes; j++ ) - { - pspriteframe = pspritegroup->frames[i]; - GL_FreeTexture( pspriteframe->gl_texturenum ); - } - } + for( j = 0; j < pspritegroup->numframes; j++ ) + { + pspriteframe = pspritegroup->frames[i]; + GL_FreeTexture( pspriteframe->gl_texturenum ); } } } } - - Mem_FreePool( &mod->mempool ); - memset( mod, 0, sizeof( *mod )); } /* @@ -495,7 +415,7 @@ mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw ) else if( frame >= psprite->numframes ) { if( frame > psprite->numframes ) - Con_Reportf( S_WARN "R_GetSpriteFrame: no such frame %d (%s)\n", frame, pModel->name ); + gEngfuncs.Con_Printf( S_WARN "R_GetSpriteFrame: no such frame %d (%s)\n", frame, pModel->name ); frame = psprite->numframes - 1; } @@ -512,7 +432,7 @@ mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw ) // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values // are positive, so we don't have to worry about division by zero - targettime = cl.time - ((int)( cl.time / fullinterval )) * fullinterval; + targettime = gpGlobals->time - ((int)( gpGlobals->time / fullinterval )) * fullinterval; for( i = 0; i < (numframes - 1); i++ ) { @@ -563,7 +483,7 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe, } else if( frame >= psprite->numframes ) { - Con_Reportf( S_WARN "R_GetSpriteFrameInterpolant: no such frame %d (%s)\n", frame, ent->model->name ); + gEngfuncs.Con_Reportf( S_WARN "R_GetSpriteFrameInterpolant: no such frame %d (%s)\n", frame, ent->model->name ); frame = psprite->numframes - 1; } @@ -576,25 +496,25 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe, // this can be happens when rendering switched between single and angled frames // or change model on replace delta-entity ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame; - ent->latched.sequencetime = cl.time; + ent->latched.sequencetime = gpGlobals->time; lerpFrac = 1.0f; } - if( ent->latched.sequencetime < cl.time ) + if( ent->latched.sequencetime < gpGlobals->time ) { if( frame != ent->latched.prevblending[1] ) { ent->latched.prevblending[0] = ent->latched.prevblending[1]; ent->latched.prevblending[1] = frame; - ent->latched.sequencetime = cl.time; + ent->latched.sequencetime = gpGlobals->time; lerpFrac = 0.0f; } - else lerpFrac = (cl.time - ent->latched.sequencetime) * 11.0f; + else lerpFrac = (gpGlobals->time - ent->latched.sequencetime) * 11.0f; } else { ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame; - ent->latched.sequencetime = cl.time; + ent->latched.sequencetime = gpGlobals->time; lerpFrac = 0.0f; } } @@ -608,7 +528,7 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe, { // reset interpolation on change model ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame; - ent->latched.sequencetime = cl.time; + ent->latched.sequencetime = gpGlobals->time; lerpFrac = 0.0f; } @@ -623,7 +543,7 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe, numframes = pspritegroup->numframes; fullinterval = pintervals[numframes-1]; jinterval = pintervals[1] - pintervals[0]; - time = cl.time; + time = gpGlobals->time; jtime = 0.0f; // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values @@ -662,25 +582,25 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe, // this can be happens when rendering switched between single and angled frames // or change model on replace delta-entity ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame; - ent->latched.sequencetime = cl.time; + ent->latched.sequencetime = gpGlobals->time; lerpFrac = 1.0f; } - if( ent->latched.sequencetime < cl.time ) + if( ent->latched.sequencetime < gpGlobals->time ) { if( frame != ent->latched.prevblending[1] ) { ent->latched.prevblending[0] = ent->latched.prevblending[1]; ent->latched.prevblending[1] = frame; - ent->latched.sequencetime = cl.time; + ent->latched.sequencetime = gpGlobals->time; lerpFrac = 0.0f; } - else lerpFrac = (cl.time - ent->latched.sequencetime) * ent->curstate.framerate; + else lerpFrac = (gpGlobals->time - ent->latched.sequencetime) * ent->curstate.framerate; } else { ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame; - ent->latched.sequencetime = cl.time; + ent->latched.sequencetime = gpGlobals->time; lerpFrac = 0.0f; } } @@ -748,7 +668,7 @@ static float R_SpriteGlowBlend( vec3_t origin, int rendermode, int renderfx, flo if( RP_NORMALPASS( )) { - tr = CL_VisTraceLine( RI.vieworg, origin, r_traceglow->value ? PM_GLASS_IGNORE : (PM_GLASS_IGNORE|PM_STUDIO_IGNORE)); + tr = gEngfuncs.EV_VisTraceLine( RI.vieworg, origin, r_traceglow->value ? PM_GLASS_IGNORE : (PM_GLASS_IGNORE|PM_STUDIO_IGNORE)); if(( 1.0f - tr->fraction ) * dist > 8.0f ) return 0.0f; @@ -908,7 +828,7 @@ void R_DrawSpriteModel( cl_entity_t *e ) { cl_entity_t *parent; - parent = CL_GetEntityByIndex( e->curstate.aiment ); + parent = gEngfuncs.GetEntityByIndex( e->curstate.aiment ); if( parent && parent->model ) { diff --git a/engine/client/gl_studio.c b/ref_gl/gl_studio.c similarity index 91% rename from engine/client/gl_studio.c rename to ref_gl/gl_studio.c index 814a3ad0..16edad48 100644 --- a/engine/client/gl_studio.c +++ b/ref_gl/gl_studio.c @@ -13,22 +13,30 @@ 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" +//#include "client.h" +#include "pmtrace.h" #define EVENT_CLIENT 5000 // less than this value it's a server-side studio events #define MAX_LOCALLIGHTS 4 -CVAR_DEFINE_AUTO( r_glowshellfreq, "2.2", 0, "glowing shell frequency update" ); -CVAR_DEFINE_AUTO( r_shadows, "0", 0, "cast shadows from models" ); +typedef struct +{ + char name[MAX_OSPATH]; + char modelname[MAX_OSPATH]; + model_t *model; +} player_model_t; + +cvar_t *r_glowshellfreq; + +cvar_t r_shadows = { "r_shadows", "0", 0 }; static vec3_t hullcolor[8] = { @@ -103,6 +111,9 @@ typedef struct vec3_t lightbonepos[MAXSTUDIOBONES][MAX_LOCALLIGHTS]; float locallightR2[MAX_LOCALLIGHTS]; + // playermodels + player_model_t player_models[MAX_CLIENTS]; + // drawelements renderer vec3_t arrayverts[MAXSTUDIOVERTS]; vec2_t arraycoord[MAXSTUDIOVERTS]; @@ -113,11 +124,11 @@ typedef struct } studio_draw_state_t; // studio-related cvars -static convar_t *r_studio_sort_textures; -static convar_t *r_drawviewmodel; -convar_t *cl_righthand = NULL; -static convar_t *cl_himodels; -static convar_t *r_studio_drawelements; +static cvar_t *r_studio_sort_textures; +static cvar_t *r_drawviewmodel; +cvar_t *cl_righthand = NULL; +static cvar_t *cl_himodels; +static cvar_t *r_studio_drawelements; static r_studio_interface_t *pStudioDraw; static studio_draw_state_t g_studio; // global studio state @@ -141,16 +152,16 @@ R_StudioInit */ void R_StudioInit( void ) { - cl_himodels = Cvar_Get( "cl_himodels", "1", FCVAR_ARCHIVE, "draw high-resolution player models in multiplayer" ); - r_studio_sort_textures = Cvar_Get( "r_studio_sort_textures", "0", FCVAR_ARCHIVE, "change draw order for additive meshes" ); - r_drawviewmodel = Cvar_Get( "r_drawviewmodel", "1", 0, "draw firstperson weapon model" ); - r_studio_drawelements = Cvar_Get( "r_studio_drawelements", "1", FCVAR_ARCHIVE, "use glDrawElements for studiomodels" ); + cl_himodels = gEngfuncs.Cvar_Get( "cl_himodels", "1", FCVAR_ARCHIVE, "draw high-resolution player models in multiplayer" ); + r_studio_sort_textures = gEngfuncs.Cvar_Get( "r_studio_sort_textures", "0", FCVAR_ARCHIVE, "change draw order for additive meshes" ); + r_drawviewmodel = gEngfuncs.Cvar_Get( "r_drawviewmodel", "1", 0, "draw firstperson weapon model" ); + r_studio_drawelements = gEngfuncs.Cvar_Get( "r_studio_drawelements", "1", FCVAR_ARCHIVE, "use glDrawElements for studiomodels" ); Matrix3x4_LoadIdentity( g_studio.rotationmatrix ); - Cvar_RegisterVariable( &r_glowshellfreq ); + r_glowshellfreq = gEngfuncs.Cvar_Get( "r_glowshellfreq", "2.2", 0, "glowing shell frequency update" ); // g-cont. cvar disabled by Valve -// Cvar_RegisterVariable( &r_shadows ); +// gEngfuncs.Cvar_RegisterVariable( &r_shadows ); g_studio.interpolate = true; g_studio.framecount = 0; @@ -169,14 +180,14 @@ static void R_StudioSetupTimings( void ) if( RI.drawWorld ) { // synchronize with server time - g_studio.time = cl.time; - g_studio.frametime = cl.time - cl.oldtime; + g_studio.time = gpGlobals->time; + g_studio.frametime = gpGlobals->time - gpGlobals->oldtime; } else { // menu stuff - g_studio.time = host.realtime; - g_studio.frametime = host.frametime; + g_studio.time = gpGlobals->realtime; + g_studio.frametime = gpGlobals->frametime; } } @@ -191,7 +202,7 @@ static qboolean R_AllowFlipViewModel( cl_entity_t *e ) { if( cl_righthand && cl_righthand->value > 0 ) { - if( e == &clgame.viewent ) + if( e == gEngfuncs.GetViewModel() ) return true; } @@ -369,11 +380,9 @@ pfnPlayerInfo player_info_t *pfnPlayerInfo( int index ) { if( !RI.drawWorld ) - return &gameui.playerinfo; + index = -1; - if( index < 0 || index > cl.maxclients ) - return NULL; - return &cl.players[index]; + return gEngfuncs.pfnPlayerInfo( index ); } /* @@ -384,7 +393,7 @@ pfnMod_ForName */ static model_t *pfnMod_ForName( const char *model, int crash ) { - return Mod_ForName( model, crash, false ); + return gEngfuncs.Mod_ForName( model, crash, false ); } /* @@ -398,10 +407,7 @@ entity_state_t *R_StudioGetPlayerState( int index ) if( !RI.drawWorld ) return &RI.currententity->curstate; - if( index < 0 || index >= cl.maxclients ) - return NULL; - - return &cl.frames[cl.parsecountmod].playerstate[index]; + return gEngfuncs.pfnGetPlayerState( index ); } /* @@ -412,7 +418,7 @@ pfnGetViewEntity */ static cl_entity_t *pfnGetViewEntity( void ) { - return &clgame.viewent; + return gEngfuncs.GetViewModel(); } /* @@ -424,8 +430,8 @@ pfnGetEngineTimes static void pfnGetEngineTimes( int *framecount, double *current, double *old ) { if( framecount ) *framecount = tr.realframecount; - if( current ) *current = cl.time; - if( old ) *old = cl.oldtime; + if( current ) *current = gpGlobals->time; + if( old ) *old = gpGlobals->oldtime; } /* @@ -450,7 +456,7 @@ R_GetChromeSprite */ static model_t *R_GetChromeSprite( void ) { - return cl_sprite_shell; + return gEngfuncs.GetDefaultSprite( REF_CHROME_SPRITE ); } /* @@ -596,12 +602,12 @@ void R_StudioSetUpTransform( cl_entity_t *e ) VectorCopy( e->angles, angles ); // interpolate monsters position (moved into UpdateEntityFields by user request) - if( e->curstate.movetype == MOVETYPE_STEP && !FBitSet( host.features, ENGINE_COMPUTE_STUDIO_LERP )) + if( e->curstate.movetype == MOVETYPE_STEP && !FBitSet( ENGINE_GET_PARM( PARM_FEATURES ), ENGINE_COMPUTE_STUDIO_LERP )) { R_StudioLerpMovement( e, g_studio.time, origin, angles ); } - if( !FBitSet( host.features, ENGINE_COMPENSATE_QUAKE_BUG )) + if( !FBitSet( ENGINE_GET_PARM( PARM_FEATURES ), ENGINE_COMPENSATE_QUAKE_BUG )) angles[PITCH] = -angles[PITCH]; // stupid quake bug // don't rotate clients, only aim @@ -673,33 +679,6 @@ float R_StudioEstimateInterpolant( cl_entity_t *e ) return dadt; } -/* -==================== -CL_GetStudioEstimatedFrame - -==================== -*/ -float CL_GetStudioEstimatedFrame( cl_entity_t *ent ) -{ - studiohdr_t *pstudiohdr; - mstudioseqdesc_t *pseqdesc; - int sequence; - - if( ent->model != NULL && ent->model->type == mod_studio ) - { - pstudiohdr = (studiohdr_t *)Mod_StudioExtradata( ent->model ); - - if( pstudiohdr ) - { - sequence = bound( 0, ent->curstate.sequence, pstudiohdr->numseq - 1 ); - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + sequence; - return R_StudioEstimateFrame( ent, pseqdesc ); - } - } - - return 0; -} - /* ==================== CL_GetSequenceDuration @@ -713,7 +692,7 @@ float CL_GetSequenceDuration( cl_entity_t *ent, int sequence ) if( ent->model != NULL && ent->model->type == mod_studio ) { - pstudiohdr = (studiohdr_t *)Mod_StudioExtradata( ent->model ); + pstudiohdr = (studiohdr_t *)gEngfuncs.Mod_Extradata( mod_studio, ent->model ); if( pstudiohdr ) { @@ -741,21 +720,21 @@ void R_StudioFxTransform( cl_entity_t *ent, matrix3x4 transform ) { case kRenderFxDistort: case kRenderFxHologram: - if( !COM_RandomLong( 0, 49 )) + if( !gEngfuncs.COM_RandomLong( 0, 49 )) { - int axis = COM_RandomLong( 0, 1 ); + int axis = gEngfuncs.COM_RandomLong( 0, 1 ); if( axis == 1 ) axis = 2; // choose between x & z - VectorScale( transform[axis], COM_RandomFloat( 1.0f, 1.484f ), transform[axis] ); + VectorScale( transform[axis], gEngfuncs.COM_RandomFloat( 1.0f, 1.484f ), transform[axis] ); } - else if( !COM_RandomLong( 0, 49 )) + else if( !gEngfuncs.COM_RandomLong( 0, 49 )) { float offset; - int axis = COM_RandomLong( 0, 1 ); + int axis = gEngfuncs.COM_RandomLong( 0, 1 ); if( axis == 1 ) axis = 2; // choose between x & z - offset = COM_RandomFloat( -10.0f, 10.0f ); - transform[COM_RandomLong( 0, 2 )][3] += offset; + offset = gEngfuncs.COM_RandomFloat( -10.0f, 10.0f ); + transform[gEngfuncs.COM_RandomLong( 0, 2 )][3] += offset; } break; case kRenderFxExplode: @@ -876,8 +855,8 @@ void R_StudioCalcRotations( cl_entity_t *e, float pos[][3], vec4_t *q, mstudiose for( i = 0; i < m_pStudioHeader->numbones; i++, pbone++, panim++ ) { - R_StudioCalcBoneQuaternion( frame, s, pbone, panim, adj, q[i] ); - R_StudioCalcBonePosition( frame, s, pbone, panim, adj, pos[i] ); + gEngfuncs.R_StudioCalcBoneQuaternion( frame, s, pbone, panim, adj, q[i] ); + gEngfuncs.R_StudioCalcBonePosition( frame, s, pbone, panim, adj, pos[i] ); } if( pseqdesc->motiontype & STUDIO_X ) pos[pseqdesc->motionbone][0] = 0.0f; @@ -909,7 +888,7 @@ void R_StudioMergeBones( cl_entity_t *e, model_t *m_pSubModel ) f = R_StudioEstimateFrame( e, pseqdesc ); - panim = R_StudioGetAnim( m_pStudioHeader, m_pSubModel, pseqdesc ); + panim = gEngfuncs.R_StudioGetAnim( m_pStudioHeader, m_pSubModel, pseqdesc ); R_StudioCalcRotations( e, pos, q, pseqdesc, panim, f ); pbones = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex); @@ -975,7 +954,7 @@ void R_StudioSetupBones( cl_entity_t *e ) f = R_StudioEstimateFrame( e, pseqdesc ); - panim = R_StudioGetAnim( m_pStudioHeader, RI.currentmodel, pseqdesc ); + panim = gEngfuncs.R_StudioGetAnim( m_pStudioHeader, RI.currentmodel, pseqdesc ); R_StudioCalcRotations( e, pos, q, pseqdesc, panim, f ); if( pseqdesc->numblends > 1 ) @@ -989,7 +968,7 @@ void R_StudioSetupBones( cl_entity_t *e ) dadt = R_StudioEstimateInterpolant( e ); s = (e->curstate.blending[0] * dadt + e->latched.prevblending[0] * (1.0f - dadt)) / 255.0f; - R_StudioSlerpBones( m_pStudioHeader->numbones, q, pos, q2, pos2, s ); + gEngfuncs.R_StudioSlerpBones( m_pStudioHeader->numbones, q, pos, q2, pos2, s ); if( pseqdesc->numblends == 4 ) { @@ -1000,10 +979,10 @@ void R_StudioSetupBones( cl_entity_t *e ) R_StudioCalcRotations( e, pos4, q4, pseqdesc, panim, f ); s = (e->curstate.blending[0] * dadt + e->latched.prevblending[0] * (1.0f - dadt)) / 255.0f; - R_StudioSlerpBones( m_pStudioHeader->numbones, q3, pos3, q4, pos4, s ); + gEngfuncs.R_StudioSlerpBones( m_pStudioHeader->numbones, q3, pos3, q4, pos4, s ); s = (e->curstate.blending[1] * dadt + e->latched.prevblending[1] * (1.0f - dadt)) / 255.0f; - R_StudioSlerpBones( m_pStudioHeader->numbones, q, pos, q3, pos3, s ); + gEngfuncs.R_StudioSlerpBones( m_pStudioHeader->numbones, q, pos, q3, pos3, s ); } } @@ -1015,7 +994,7 @@ void R_StudioSetupBones( cl_entity_t *e ) float s; pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->latched.prevsequence; - panim = R_StudioGetAnim( m_pStudioHeader, RI.currentmodel, pseqdesc ); + panim = gEngfuncs.R_StudioGetAnim( m_pStudioHeader, RI.currentmodel, pseqdesc ); // clip prevframe R_StudioCalcRotations( e, pos1b, q1b, pseqdesc, panim, e->latched.prevframe ); @@ -1026,7 +1005,7 @@ void R_StudioSetupBones( cl_entity_t *e ) R_StudioCalcRotations( e, pos2, q2, pseqdesc, panim, e->latched.prevframe ); s = (e->latched.prevseqblending[0]) / 255.0f; - R_StudioSlerpBones( m_pStudioHeader->numbones, q1b, pos1b, q2, pos2, s ); + gEngfuncs.R_StudioSlerpBones( m_pStudioHeader->numbones, q1b, pos1b, q2, pos2, s ); if( pseqdesc->numblends == 4 ) { @@ -1037,15 +1016,15 @@ void R_StudioSetupBones( cl_entity_t *e ) R_StudioCalcRotations( e, pos4, q4, pseqdesc, panim, e->latched.prevframe ); s = (e->latched.prevseqblending[0]) / 255.0f; - R_StudioSlerpBones( m_pStudioHeader->numbones, q3, pos3, q4, pos4, s ); + gEngfuncs.R_StudioSlerpBones( m_pStudioHeader->numbones, q3, pos3, q4, pos4, s ); s = (e->latched.prevseqblending[1]) / 255.0f; - R_StudioSlerpBones( m_pStudioHeader->numbones, q1b, pos1b, q3, pos3, s ); + gEngfuncs.R_StudioSlerpBones( m_pStudioHeader->numbones, q1b, pos1b, q3, pos3, s ); } } s = 1.0f - ( g_studio.time - e->latched.sequencetime ) / 0.2f; - R_StudioSlerpBones( m_pStudioHeader->numbones, q, pos, q1b, pos1b, s ); + gEngfuncs.R_StudioSlerpBones( m_pStudioHeader->numbones, q, pos, q1b, pos1b, s ); } else { @@ -1065,7 +1044,7 @@ void R_StudioSetupBones( cl_entity_t *e ) pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pPlayerInfo->gaitsequence; - panim = R_StudioGetAnim( m_pStudioHeader, RI.currentmodel, pseqdesc ); + panim = gEngfuncs.R_StudioGetAnim( m_pStudioHeader, RI.currentmodel, pseqdesc ); R_StudioCalcRotations( e, pos2, q2, pseqdesc, panim, m_pPlayerInfo->gaitframe ); for( i = 0; i < m_pStudioHeader->numbones; i++ ) @@ -1165,9 +1144,9 @@ void R_StudioBuildNormalTable( void ) } } - g_studio.chrome_origin[0] = cos( r_glowshellfreq.value * g_studio.time ) * 4000.0f; - g_studio.chrome_origin[1] = sin( r_glowshellfreq.value * g_studio.time ) * 4000.0f; - g_studio.chrome_origin[2] = cos( r_glowshellfreq.value * g_studio.time * 0.33f ) * 4000.0f; + g_studio.chrome_origin[0] = cos( r_glowshellfreq->value * g_studio.time ) * 4000.0f; + g_studio.chrome_origin[1] = sin( r_glowshellfreq->value * g_studio.time ) * 4000.0f; + g_studio.chrome_origin[2] = cos( r_glowshellfreq->value * g_studio.time * 0.33f ) * 4000.0f; if( e->curstate.rendercolor.r || e->curstate.rendercolor.g || e->curstate.rendercolor.b ) TriColor4ub( e->curstate.rendercolor.r, e->curstate.rendercolor.g, e->curstate.rendercolor.b, 255 ); @@ -1387,7 +1366,7 @@ R_StudioDynamicLight */ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight ) { - movevars_t *mv = &clgame.movevars; + movevars_t *mv = gEngfuncs.pfnGetMoveVars(); vec3_t lightDir, vecSrc, vecEnd; vec3_t origin, dist, finalLight; float add, radius, total; @@ -1423,7 +1402,7 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight ) msurface_t *psurf = NULL; pmtrace_t trace; - if( FBitSet( host.features, ENGINE_WRITE_LARGE_COORD )) + if( FBitSet( ENGINE_GET_PARM( PARM_FEATURES ), ENGINE_WRITE_LARGE_COORD )) { vecEnd[0] = origin[0] - mv->skyvec_x * 65536.0f; vecEnd[1] = origin[1] - mv->skyvec_y * 65536.0f; @@ -1436,17 +1415,17 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight ) vecEnd[2] = origin[2] - mv->skyvec_z * 8192.0f; } - trace = CL_TraceLine( vecSrc, vecEnd, PM_WORLD_ONLY ); - if( trace.ent > 0 ) psurf = PM_TraceSurface( &clgame.pmove->physents[trace.ent], vecSrc, vecEnd ); - else psurf = PM_TraceSurface( clgame.pmove->physents, vecSrc, vecEnd ); - + trace = gEngfuncs.CL_TraceLine( vecSrc, vecEnd, PM_WORLD_ONLY ); + if( trace.ent > 0 ) psurf = gEngfuncs.EV_TraceSurface( trace.ent, vecSrc, vecEnd ); + else psurf = gEngfuncs.EV_TraceSurface( 0, vecSrc, vecEnd ); + if( FBitSet( ent->model->flags, STUDIO_FORCE_SKYLIGHT ) || ( psurf && FBitSet( psurf->flags, SURF_DRAWSKY ))) { VectorSet( lightDir, mv->skyvec_x, mv->skyvec_y, mv->skyvec_z ); - light.r = LightToTexGamma( bound( 0, mv->skycolor_r, 255 )); - light.g = LightToTexGamma( bound( 0, mv->skycolor_g, 255 )); - light.b = LightToTexGamma( bound( 0, mv->skycolor_b, 255 )); + light.r = gEngfuncs.LightToTexGamma( bound( 0, mv->skycolor_r, 255 )); + light.g = gEngfuncs.LightToTexGamma( bound( 0, mv->skycolor_g, 255 )); + light.b = gEngfuncs.LightToTexGamma( bound( 0, mv->skycolor_b, 255 )); } } @@ -1507,8 +1486,10 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight ) // scale lightdir by light intentsity VectorScale( lightDir, total, lightDir ); - for( lnum = 0, dl = cl_dlights; lnum < MAX_DLIGHTS; lnum++, dl++ ) + for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ ) { + dl = gEngfuncs.GetDynamicLight( lnum ); + if( dl->die < g_studio.time || !r_dynamic->value ) continue; @@ -1527,9 +1508,9 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight ) VectorAdd( lightDir, dist, lightDir ); - finalLight[0] += LightToTexGamma( dl->color.r ) * ( add / 256.0f ) * 2.0f; - finalLight[1] += LightToTexGamma( dl->color.g ) * ( add / 256.0f ) * 2.0f; - finalLight[2] += LightToTexGamma( dl->color.b ) * ( add / 256.0f ) * 2.0f; + finalLight[0] += gEngfuncs.LightToTexGamma( dl->color.r ) * ( add / 256.0f ) * 2.0f; + finalLight[1] += gEngfuncs.LightToTexGamma( dl->color.g ) * ( add / 256.0f ) * 2.0f; + finalLight[2] += gEngfuncs.LightToTexGamma( dl->color.b ) * ( add / 256.0f ) * 2.0f; } } @@ -1588,8 +1569,10 @@ void R_StudioEntityLight( alight_t *lightinfo ) dist2 = 1000000.0f; k = 0; - for( lnum = 0, el = cl_elights; lnum < MAX_ELIGHTS; lnum++, el++ ) + for( lnum = 0; lnum < MAX_ELIGHTS; lnum++ ) { + el = gEngfuncs.GetEntityLight( lnum ); + if( el->die < g_studio.time || el->radius <= 0.0f ) continue; @@ -1627,9 +1610,9 @@ void R_StudioEntityLight( alight_t *lightinfo ) if( k != -1 ) { - g_studio.locallightcolor[k].r = LightToTexGamma( el->color.r ); - g_studio.locallightcolor[k].g = LightToTexGamma( el->color.g ); - g_studio.locallightcolor[k].b = LightToTexGamma( el->color.b ); + g_studio.locallightcolor[k].r = gEngfuncs.LightToTexGamma( el->color.r ); + g_studio.locallightcolor[k].g = gEngfuncs.LightToTexGamma( el->color.g ); + g_studio.locallightcolor[k].b = gEngfuncs.LightToTexGamma( el->color.b ); g_studio.locallightR2[k] = r2; g_studio.locallight[k] = el; lstrength[k] = minstrength; @@ -1865,7 +1848,7 @@ static void R_StudioSetupSkin( studiohdr_t *ptexturehdr, int index ) return; // NOTE: user may ignore to call StudioRemapColors and remap_info will be unavailable - if( m_fDoRemap ) ptexture = CL_GetRemapInfoForEntity( RI.currententity )->ptexture; + if( m_fDoRemap ) ptexture = gEngfuncs.CL_GetRemapInfoForEntity( RI.currententity )->ptexture; if( !ptexture ) ptexture = (mstudiotexture_t *)((byte *)ptexturehdr + ptexturehdr->textureindex); // fallback if( r_lightmap->value && !r_fullbright->value ) @@ -1885,13 +1868,13 @@ mstudiotexture_t *R_StudioGetTexture( cl_entity_t *e ) mstudiotexture_t *ptexture; studiohdr_t *phdr, *thdr; - if(( phdr = Mod_StudioExtradata( e->model )) == NULL ) + if(( phdr = gEngfuncs.Mod_Extradata( mod_studio, e->model )) == NULL ) return NULL; thdr = m_pStudioHeader; - if( !thdr ) return NULL; + if( !thdr ) return NULL; - if( m_fDoRemap ) ptexture = CL_GetRemapInfoForEntity( e )->ptexture; + if( m_fDoRemap ) ptexture = gEngfuncs.CL_GetRemapInfoForEntity( e )->ptexture; else ptexture = (mstudiotexture_t *)((byte *)thdr + thdr->textureindex); return ptexture; @@ -1902,7 +1885,7 @@ void R_StudioSetRenderamt( int iRenderamt ) if( !RI.currententity ) return; RI.currententity->curstate.renderamt = iRenderamt; - tr.blend = CL_FxBlend( RI.currententity ) / 255.0f; + tr.blend = gEngfuncs.CL_FxBlend( RI.currententity ) / 255.0f; } /* @@ -1929,7 +1912,7 @@ void R_StudioRenderShadow( int iSprite, float *p1, float *p2, float *p3, float * if( !p1 || !p2 || !p3 || !p4 ) return; - if( TriSpriteTexture( CL_ModelHandle( iSprite ), 0 )) + if( TriSpriteTexture( gEngfuncs.pfnGetModelByIndex( iSprite ), 0 )) { TriRenderMode( kRenderTransAlpha ); TriColor4f( 0.0f, 0.0f, 0.0f, 1.0f ); @@ -2556,7 +2539,7 @@ static void R_StudioDrawAbsBBox( void ) int i; // looks ugly, skip - if( RI.currententity == &clgame.viewent ) + if( RI.currententity == gEngfuncs.GetViewModel() ) return; if( !R_StudioComputeBBox( p )) @@ -2690,17 +2673,22 @@ R_StudioSetRemapColors =============== */ -void R_StudioSetRemapColors( int newTop, int newBottom ) +static void R_StudioSetRemapColors( int newTop, int newBottom ) { - CL_AllocRemapInfo( newTop, newBottom ); + gEngfuncs.CL_AllocRemapInfo( newTop, newBottom ); - if( CL_GetRemapInfoForEntity( RI.currententity )) + if( gEngfuncs.CL_GetRemapInfoForEntity( RI.currententity )) { - CL_UpdateRemapInfo( newTop, newBottom ); + gEngfuncs.CL_UpdateRemapInfo( newTop, newBottom ); m_fDoRemap = true; } } +void R_StudioResetPlayerModels( void ) +{ + memset( g_studio.player_models, 0, sizeof( g_studio.player_models )); +} + /* =============== R_StudioSetupPlayerModel @@ -2709,25 +2697,13 @@ R_StudioSetupPlayerModel */ static model_t *R_StudioSetupPlayerModel( int index ) { - player_info_t *info; + player_info_t *info = gEngfuncs.pfnPlayerInfo( index ); player_model_t *state; - if( !RI.drawWorld ) - { - // we are in gameui. - info = &gameui.playerinfo; - } - else - { - if( index < 0 || index >= cl.maxclients ) - return NULL; // bad client ? - info = &cl.players[index]; - } - - state = &cl.player_models[index]; + state = &g_studio.player_models[index]; // g-cont: force for "dev-mode", non-local games and menu preview - if(( host_developer.value || !Host_IsLocalGame( ) || !RI.drawWorld ) && info->model[0] ) + if(( gpGlobals->developer || !ENGINE_GET_PARM( PARM_LOCAL_GAME ) || !RI.drawWorld ) && info->model[0] ) { if( Q_strcmp( state->name, info->model )) { @@ -2736,8 +2712,8 @@ static model_t *R_StudioSetupPlayerModel( int index ) Q_snprintf( state->modelname, sizeof( state->modelname ), "models/player/%s/%s.mdl", info->model, info->model ); - if( FS_FileExists( state->modelname, false )) - state->model = Mod_ForName( state->modelname, false, true ); + if( gEngfuncs.FS_FileExists( state->modelname, false )) + state->model = gEngfuncs.Mod_ForName( state->modelname, false, true ); else state->model = NULL; if( !state->model ) @@ -2778,7 +2754,7 @@ int R_GetEntityRenderMode( cl_entity_t *ent ) RI.currententity = oldent; - if(( phdr = Mod_StudioExtradata( model )) == NULL ) + if(( phdr = gEngfuncs.Mod_Extradata( mod_studio, model )) == NULL ) { if( R_ModelOpaque( ent->curstate.rendermode )) { @@ -2832,11 +2808,11 @@ static void R_StudioClientEvents( void ) if( FBitSet( e->curstate.effects, EF_MUZZLEFLASH )) { - dlight_t *el = CL_AllocElight( 0 ); + dlight_t *el = gEngfuncs.CL_AllocElight( 0 ); ClearBits( e->curstate.effects, EF_MUZZLEFLASH ); VectorCopy( e->attachment[0], el->origin ); - el->die = cl.time + 0.05f; + el->die = gpGlobals->time + 0.05f; el->color.r = 255; el->color.g = 192; el->color.b = 64; @@ -2852,7 +2828,7 @@ static void R_StudioClientEvents( void ) return; end = R_StudioEstimateFrame( e, pseqdesc ); - start = end - e->curstate.framerate * host.frametime * pseqdesc->fps; + start = end - e->curstate.framerate * gpGlobals->frametime * pseqdesc->fps; pevent = (mstudioevent_t *)((byte *)m_pStudioHeader + pseqdesc->eventindex); if( e->latched.sequencetime == e->curstate.animtime ) @@ -2868,7 +2844,7 @@ static void R_StudioClientEvents( void ) continue; if( (float)pevent[i].frame > start && pevent[i].frame <= end ) - clgame.dllFuncs.pfnStudioEvent( &pevent[i], e ); + gEngfuncs.pfnStudioEvent( &pevent[i], e ); } } @@ -3377,14 +3353,14 @@ static int R_StudioDrawPlayer( int flags, entity_state_t *pplayer ) m_nPlayerIndex = pplayer->number - 1; - if( m_nPlayerIndex < 0 || m_nPlayerIndex >= cl.maxclients ) + if( m_nPlayerIndex < 0 || m_nPlayerIndex >= ENGINE_GET_PARM( PARM_MAX_CLIENTS ) ) return 0; RI.currentmodel = R_StudioSetupPlayerModel( m_nPlayerIndex ); if( RI.currentmodel == NULL ) return 0; - R_StudioSetHeader((studiohdr_t *)Mod_StudioExtradata( RI.currentmodel )); + R_StudioSetHeader((studiohdr_t *)gEngfuncs.Mod_Extradata( mod_studio, RI.currentmodel )); if( pplayer->gaitsequence ) { @@ -3446,7 +3422,7 @@ static int R_StudioDrawPlayer( int flags, entity_state_t *pplayer ) // copy attachments into global entity array if( RI.currententity->index > 0 ) { - cl_entity_t *ent = CL_GetEntityByIndex( RI.currententity->index ); + cl_entity_t *ent = gEngfuncs.GetEntityByIndex( RI.currententity->index ); memcpy( ent->attachment, RI.currententity->attachment, sizeof( vec3_t ) * 4 ); } } @@ -3459,7 +3435,7 @@ static int R_StudioDrawPlayer( int flags, entity_state_t *pplayer ) RI.currententity->curstate.body = 255; } - if( !( !host_developer.value && cl.maxclients == 1 ) && ( RI.currentmodel == RI.currententity->model )) + if( !( !gpGlobals->developer && ENGINE_GET_PARM( PARM_MAX_CLIENTS ) == 1 ) && ( RI.currentmodel == RI.currententity->model )) RI.currententity->curstate.body = 1; // force helmet lighting.plightvec = dir; @@ -3489,9 +3465,9 @@ static int R_StudioDrawPlayer( int flags, entity_state_t *pplayer ) if( pplayer->weaponmodel ) { cl_entity_t saveent = *RI.currententity; - model_t *pweaponmodel = CL_ModelHandle( pplayer->weaponmodel ); + model_t *pweaponmodel = gEngfuncs.pfnGetModelByIndex( pplayer->weaponmodel ); - m_pStudioHeader = (studiohdr_t *)Mod_StudioExtradata( pweaponmodel ); + m_pStudioHeader = (studiohdr_t *)gEngfuncs.Mod_Extradata( mod_studio, pweaponmodel ); R_StudioMergeBones( RI.currententity, pweaponmodel ); R_StudioSetupLighting( &lighting ); @@ -3521,7 +3497,8 @@ static int R_StudioDrawModel( int flags ) entity_state_t deadplayer; int result; - if( RI.currententity->curstate.renderamt <= 0 || RI.currententity->curstate.renderamt > cl.maxclients ) + if( RI.currententity->curstate.renderamt <= 0 || + RI.currententity->curstate.renderamt > ENGINE_GET_PARM( PARM_MAX_CLIENTS ) ) return 0; // get copy of player @@ -3543,7 +3520,7 @@ static int R_StudioDrawModel( int flags ) return result; } - R_StudioSetHeader((studiohdr_t *)Mod_StudioExtradata( RI.currentmodel )); + R_StudioSetHeader((studiohdr_t *)gEngfuncs.Mod_Extradata( mod_studio, RI.currentmodel )); R_StudioSetUpTransform( RI.currententity ); @@ -3574,7 +3551,7 @@ static int R_StudioDrawModel( int flags ) // copy attachments into global entity array if( RI.currententity->index > 0 ) { - cl_entity_t *ent = CL_GetEntityByIndex( RI.currententity->index ); + cl_entity_t *ent = gEngfuncs.GetEntityByIndex( RI.currententity->index ); memcpy( ent->attachment, RI.currententity->attachment, sizeof( vec3_t ) * 4 ); } } @@ -3643,7 +3620,7 @@ void R_DrawStudioModel( cl_entity_t *e ) { if( e->curstate.movetype == MOVETYPE_FOLLOW && e->curstate.aiment > 0 ) { - cl_entity_t *parent = CL_GetEntityByIndex( e->curstate.aiment ); + cl_entity_t *parent = gEngfuncs.GetEntityByIndex( e->curstate.aiment ); if( parent && parent->model && parent->model->type == mod_studio ) { @@ -3667,26 +3644,28 @@ R_RunViewmodelEvents void R_RunViewmodelEvents( void ) { int i; + vec3_t simorg; if( r_drawviewmodel->value == 0 ) return; - if( CL_IsThirdPerson( )) + if( ENGINE_GET_PARM( PARM_THIRDPERSON )) return; // ignore in thirdperson, camera view or client is died - if( !RP_NORMALPASS() || cl.local.health <= 0 || cl.viewentity != ( cl.playernum + 1 )) + if( !RP_NORMALPASS() || ENGINE_GET_PARM( PARM_LOCAL_HEALTH ) <= 0 || !CL_IsViewEntityLocalPlayer()) return; - RI.currententity = &clgame.viewent; + RI.currententity = gEngfuncs.GetViewModel(); if( !RI.currententity->model || RI.currententity->model->type != mod_studio ) return; R_StudioSetupTimings(); + gEngfuncs.GetPredictedOrigin( simorg ); for( i = 0; i < 4; i++ ) - VectorCopy( cl.simorg, RI.currententity->attachment[i] ); + VectorCopy( simorg, RI.currententity->attachment[i] ); RI.currentmodel = RI.currententity->model; R_StudioDrawModelInternal( RI.currententity, STUDIO_EVENTS ); @@ -3699,13 +3678,13 @@ R_GatherPlayerLight */ void R_GatherPlayerLight( void ) { - cl_entity_t *view = &clgame.viewent; + cl_entity_t *view = gEngfuncs.GetViewModel(); colorVec c; tr.ignore_lightgamma = true; c = R_LightPoint( view->origin ); tr.ignore_lightgamma = false; - cl.local.light_level = (c.r + c.g + c.b) / 3; + gEngfuncs.SetLocalLightLevel( ( c.r + c.g + c.b ) / 3 ); } /* @@ -3715,21 +3694,21 @@ R_DrawViewModel */ void R_DrawViewModel( void ) { - cl_entity_t *view = &clgame.viewent; + cl_entity_t *view = gEngfuncs.GetViewModel(); R_GatherPlayerLight(); if( r_drawviewmodel->value == 0 ) return; - if( CL_IsThirdPerson( )) + if( ENGINE_GET_PARM( PARM_THIRDPERSON )) return; // ignore in thirdperson, camera view or client is died - if( !RP_NORMALPASS() || cl.local.health <= 0 || cl.viewentity != ( cl.playernum + 1 )) + if( !RP_NORMALPASS() || ENGINE_GET_PARM( PARM_LOCAL_HEALTH ) <= 0 || !CL_IsViewEntityLocalPlayer()) return; - tr.blend = CL_FxBlend( view ) / 255.0f; + tr.blend = gEngfuncs.CL_FxBlend( view ) / 255.0f; if( !R_ModelOpaque( view->curstate.rendermode ) && tr.blend <= 0.0f ) return; // invisible ? @@ -3844,10 +3823,10 @@ static void R_StudioLoadTexture( model_t *mod, studiohdr_t *phdr, mstudiotexture // NOTE: replace index with pointer to start of imagebuffer, ImageLib expected it //ptexture->index = (int)((byte *)phdr) + ptexture->index; - Image_SetMDLPointer((byte *)phdr + ptexture->index); + gEngfuncs.Image_SetMDLPointer((byte *)phdr + ptexture->index); size = sizeof( mstudiotexture_t ) + ptexture->width * ptexture->height + 768; - if( FBitSet( host.features, ENGINE_LOAD_DELUXEDATA ) && FBitSet( ptexture->flags, STUDIO_NF_MASKED )) + if( FBitSet( ENGINE_GET_PARM( PARM_FEATURES ), ENGINE_LOAD_DELUXEDATA ) && FBitSet( ptexture->flags, STUDIO_NF_MASKED )) flags |= TF_KEEP_SOURCE; // Paranoia2 texture alpha-tracing // build the texname @@ -3876,7 +3855,7 @@ void Mod_StudioLoadTextures( model_t *mod, void *data ) mstudiotexture_t *ptexture; int i; - if( !phdr || host.type == HOST_DEDICATED ) + if( !phdr ) return; ptexture = (mstudiotexture_t *)(((byte *)phdr) + phdr->textureindex); @@ -3889,7 +3868,7 @@ void Mod_StudioLoadTextures( model_t *mod, void *data ) /* ================= -Mod_StudioLoadTextures +Mod_StudioUnloadTextures ================= */ void Mod_StudioUnloadTextures( void *data ) @@ -3898,7 +3877,7 @@ void Mod_StudioUnloadTextures( void *data ) mstudiotexture_t *ptexture; int i; - if( !phdr || host.type == HOST_DEDICATED ) + if( !phdr ) return; ptexture = (mstudiotexture_t *)(((byte *)phdr) + phdr->textureindex); @@ -3911,21 +3890,51 @@ void Mod_StudioUnloadTextures( void *data ) GL_FreeTexture( ptexture[i].index ); } } - + +static model_t *pfnModelHandle( int modelindex ) +{ + return gEngfuncs.pfnGetModelByIndex( modelindex ); +} + +static void *pfnMod_CacheCheck( struct cache_user_s *c ) +{ + return gEngfuncs.Mod_CacheCheck( c ); +} + +static void *pfnMod_StudioExtradata( model_t *mod ) +{ + return gEngfuncs.Mod_Extradata( mod_studio, mod ); +} + +static void pfnMod_LoadCacheFile( const char *path, struct cache_user_s *cu ) +{ + gEngfuncs.Mod_LoadCacheFile( path, cu ); +} + +static cvar_t *pfnGetCvarPointer( const char *name ) +{ + return (cvar_t*)gEngfuncs.pfnGetCvarPointer( name, 0 ); +} + +static void *pfnMod_Calloc( int number, size_t size ) +{ + return gEngfuncs.Mod_Calloc( number, size ); +} + static engine_studio_api_t gStudioAPI = { - Mod_Calloc, - Mod_CacheCheck, - Mod_LoadCacheFile, + pfnMod_Calloc, + pfnMod_CacheCheck, + pfnMod_LoadCacheFile, pfnMod_ForName, - Mod_StudioExtradata, - CL_ModelHandle, + pfnMod_StudioExtradata, + pfnModelHandle, pfnGetCurrentEntity, pfnPlayerInfo, R_StudioGetPlayerState, pfnGetViewEntity, pfnGetEngineTimes, - pfnCVarGetPointer, + pfnGetCvarPointer, pfnGetViewInfo, R_GetChromeSprite, pfnGetModelCounters, @@ -3980,11 +3989,14 @@ void CL_InitStudioAPI( void ) { pStudioDraw = &gStudioDraw; - // Xash will be used internal StudioModelRenderer - if( !clgame.dllFuncs.pfnGetStudioModelInterface ) - return; + // trying to grab them from client.dll + cl_righthand = gEngfuncs.pfnGetCvarPointer( "cl_righthand", 0 ); - if( clgame.dllFuncs.pfnGetStudioModelInterface( STUDIO_INTERFACE_VERSION, &pStudioDraw, &gStudioAPI )) + if( cl_righthand == NULL ) + cl_righthand = gEngfuncs.Cvar_Get( "cl_righthand", "0", FCVAR_ARCHIVE, "flip viewmodel (left to right)" ); + + // Xash will be used internal StudioModelRenderer + if( gEngfuncs.pfnGetStudioModelInterface( STUDIO_INTERFACE_VERSION, &pStudioDraw, &gStudioAPI )) return; // NOTE: we always return true even if game interface was not correct diff --git a/ref_gl/gl_triapi.c b/ref_gl/gl_triapi.c new file mode 100644 index 00000000..5803c906 --- /dev/null +++ b/ref_gl/gl_triapi.c @@ -0,0 +1,347 @@ +/* +gl_triapi.c - TriAPI draw methods +Copyright (C) 2011 Uncle Mike +Copyright (C) 2019 a1batross + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + +#include "gl_local.h" +#include "const.h" + +static struct +{ + int renderMode; // override kRenderMode from TriAPI + vec4_t triRGBA; +} ds; + +/* +=============================================================== + + TRIAPI IMPLEMENTATION + +=============================================================== +*/ +/* +============= +TriRenderMode + +set rendermode +============= +*/ +void TriRenderMode( int mode ) +{ + ds.renderMode = mode; + switch( mode ) + { + case kRenderNormal: + pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + pglDisable( GL_BLEND ); + pglDepthMask( GL_TRUE ); + break; + case kRenderTransAlpha: + pglEnable( GL_BLEND ); + pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + pglDepthMask( GL_FALSE ); + break; + case kRenderTransColor: + case kRenderTransTexture: + pglEnable( GL_BLEND ); + pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + break; + case kRenderGlow: + case kRenderTransAdd: + pglBlendFunc( GL_SRC_ALPHA, GL_ONE ); + pglEnable( GL_BLEND ); + pglDepthMask( GL_FALSE ); + break; + } +} + +/* +============= +TriBegin + +begin triangle sequence +============= +*/ +void TriBegin( int mode ) +{ + switch( mode ) + { + case TRI_POINTS: + mode = GL_POINTS; + break; + case TRI_TRIANGLES: + mode = GL_TRIANGLES; + break; + case TRI_TRIANGLE_FAN: + mode = GL_TRIANGLE_FAN; + break; + case TRI_QUADS: + mode = GL_QUADS; + break; + case TRI_LINES: + mode = GL_LINES; + break; + case TRI_TRIANGLE_STRIP: + mode = GL_TRIANGLE_STRIP; + break; + case TRI_QUAD_STRIP: + mode = GL_QUAD_STRIP; + break; + case TRI_POLYGON: + default: + mode = GL_POLYGON; + break; + } + + pglBegin( mode ); +} + +/* +============= +TriEnd + +draw triangle sequence +============= +*/ +void TriEnd( void ) +{ + pglEnd( ); +} + +/* +============= +_TriColor4f + +============= +*/ +void _TriColor4f( float r, float g, float b, float a ) +{ + pglColor4f( r, g, b, a ); +} + +/* +============= +TriColor4ub + +============= +*/ +void TriColor4ub( byte r, byte g, byte b, byte a ) +{ + ds.triRGBA[0] = r * (1.0f / 255.0f); + ds.triRGBA[1] = g * (1.0f / 255.0f); + ds.triRGBA[2] = b * (1.0f / 255.0f); + ds.triRGBA[3] = a * (1.0f / 255.0f); + + _TriColor4f( ds.triRGBA[0], ds.triRGBA[1], ds.triRGBA[2], 1.0f ); +} + +/* +================= +TriColor4f +================= +*/ +void TriColor4f( float r, float g, float b, float a ) +{ + if( ds.renderMode == kRenderTransAlpha ) + TriColor4ub( r * 255.9f, g * 255.9f, b * 255.9f, a * 255.0f ); + else _TriColor4f( r * a, g * a, b * a, 1.0 ); + + ds.triRGBA[0] = r; + ds.triRGBA[1] = g; + ds.triRGBA[2] = b; + ds.triRGBA[3] = a; +} + +/* +============= +TriTexCoord2f + +============= +*/ +void TriTexCoord2f( float u, float v ) +{ + pglTexCoord2f( u, v ); +} + +/* +============= +TriVertex3fv + +============= +*/ +void TriVertex3fv( const float *v ) +{ + pglVertex3fv( v ); +} + +/* +============= +TriVertex3f + +============= +*/ +void TriVertex3f( float x, float y, float z ) +{ + pglVertex3f( x, y, z ); +} + +/* +============= +TriWorldToScreen + +convert world coordinates (x,y,z) into screen (x, y) +============= +*/ +int TriWorldToScreen( const float *world, float *screen ) +{ + int retval; + + retval = R_WorldToScreen( world, screen ); + + screen[0] = 0.5f * screen[0] * (float)RI.viewport[2]; + screen[1] = -0.5f * screen[1] * (float)RI.viewport[3]; + screen[0] += 0.5f * (float)RI.viewport[2]; + screen[1] += 0.5f * (float)RI.viewport[3]; + + return retval; +} + +/* +============= +TriSpriteTexture + +bind current texture +============= +*/ +int TriSpriteTexture( model_t *pSpriteModel, int frame ) +{ + int gl_texturenum; + + if(( gl_texturenum = R_GetSpriteTexture( pSpriteModel, frame )) == 0 ) + return 0; + + if( gl_texturenum <= 0 || gl_texturenum > MAX_TEXTURES ) + gl_texturenum = tr.defaultTexture; + + GL_Bind( XASH_TEXTURE0, gl_texturenum ); + + return 1; +} + +/* +============= +TriFog + +enables global fog on the level +============= +*/ +void TriFog( float flFogColor[3], float flStart, float flEnd, int bOn ) +{ + // overrided by internal fog + if( RI.fogEnabled ) return; + RI.fogCustom = bOn; + + // check for invalid parms + if( flEnd <= flStart ) + { + RI.fogCustom = false; + pglDisable( GL_FOG ); + return; + } + + if( RI.fogCustom ) + pglEnable( GL_FOG ); + else pglDisable( GL_FOG ); + + // copy fog params + RI.fogColor[0] = flFogColor[0] / 255.0f; + RI.fogColor[1] = flFogColor[1] / 255.0f; + RI.fogColor[2] = flFogColor[2] / 255.0f; + RI.fogStart = flStart; + RI.fogColor[3] = 1.0f; + RI.fogDensity = 0.0f; + RI.fogSkybox = true; + RI.fogEnd = flEnd; + + pglFogi( GL_FOG_MODE, GL_LINEAR ); + pglFogfv( GL_FOG_COLOR, RI.fogColor ); + pglFogf( GL_FOG_START, RI.fogStart ); + pglFogf( GL_FOG_END, RI.fogEnd ); + pglHint( GL_FOG_HINT, GL_NICEST ); +} + +/* +============= +TriGetMatrix + +very strange export +============= +*/ +void TriGetMatrix( const int pname, float *matrix ) +{ + pglGetFloatv( pname, matrix ); +} + +/* +============= +TriForParams + +============= +*/ +void TriFogParams( float flDensity, int iFogSkybox ) +{ + RI.fogDensity = flDensity; + RI.fogSkybox = iFogSkybox; +} + +/* +============= +TriCullFace + +============= +*/ +void TriCullFace( TRICULLSTYLE mode ) +{ + int glMode; + + switch( mode ) + { + case TRI_FRONT: + glMode = GL_FRONT; + break; + default: + glMode = GL_NONE; + break; + } + + GL_Cull( mode ); +} + +/* +============= +TriBrightness +============= +*/ +void TriBrightness( float brightness ) +{ + float r, g, b; + + r = ds.triRGBA[0] * ds.triRGBA[3] * brightness; + g = ds.triRGBA[1] * ds.triRGBA[3] * brightness; + b = ds.triRGBA[2] * ds.triRGBA[3] * brightness; + + _TriColor4f( r, g, b, 1.0f ); +} + diff --git a/ref_gl/gl_vgui.c b/ref_gl/gl_vgui.c new file mode 100644 index 00000000..029d8499 --- /dev/null +++ b/ref_gl/gl_vgui.c @@ -0,0 +1,253 @@ +/* +gl_vgui.c - OpenGL vgui draw methods +Copyright (C) 2011 Uncle Mike +Copyright (C) 2019 a1batross + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + +#include "gl_local.h" + +#define VGUI_MAX_TEXTURES ( MAX_TEXTURES / 2 ) // a half of total textures count + +static int g_textures[VGUI_MAX_TEXTURES]; +static int g_textureId = 0; +static int g_iBoundTexture; + +/* +================ +VGUI_DrawInit + +Startup VGUI backend +================ +*/ +void GAME_EXPORT VGUI_DrawInit( void ) +{ + memset( g_textures, 0, sizeof( g_textures )); + g_textureId = g_iBoundTexture = 0; +} + +/* +================ +VGUI_DrawShutdown + +Release all textures +================ +*/ +void GAME_EXPORT VGUI_DrawShutdown( void ) +{ + int i; + + for( i = 1; i < g_textureId; i++ ) + { + GL_FreeTexture( g_textures[i] ); + } +} + +/* +================ +VGUI_GenerateTexture + +generate unique texture number +================ +*/ +int GAME_EXPORT VGUI_GenerateTexture( void ) +{ + if( ++g_textureId >= VGUI_MAX_TEXTURES ) + gEngfuncs.Host_Error( "VGUI_GenerateTexture: VGUI_MAX_TEXTURES limit exceeded\n" ); + return g_textureId; +} + +/* +================ +VGUI_UploadTexture + +Upload texture into video memory +================ +*/ +void GAME_EXPORT VGUI_UploadTexture( int id, const char *buffer, int width, int height ) +{ + rgbdata_t r_image; + char texName[32]; + + if( id <= 0 || id >= VGUI_MAX_TEXTURES ) + { + gEngfuncs.Con_DPrintf( S_ERROR "VGUI_UploadTexture: bad texture %i. Ignored\n", id ); + return; + } + + Q_snprintf( texName, sizeof( texName ), "*vgui%i", id ); + memset( &r_image, 0, sizeof( r_image )); + + r_image.width = width; + r_image.height = height; + r_image.type = PF_RGBA_32; + r_image.size = r_image.width * r_image.height * 4; + r_image.flags = IMAGE_HAS_COLOR|IMAGE_HAS_ALPHA; + r_image.buffer = (byte *)buffer; + + g_textures[id] = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE ); +} + +/* +================ +VGUI_CreateTexture + +Create empty rgba texture and upload them into video memory +================ +*/ +void GAME_EXPORT VGUI_CreateTexture( int id, int width, int height ) +{ + rgbdata_t r_image; + char texName[32]; + + if( id <= 0 || id >= VGUI_MAX_TEXTURES ) + { + gEngfuncs.Con_Reportf( S_ERROR "VGUI_CreateTexture: bad texture %i. Ignored\n", id ); + return; + } + + Q_snprintf( texName, sizeof( texName ), "*vgui%i", id ); + memset( &r_image, 0, sizeof( r_image )); + + r_image.width = width; + r_image.height = height; + r_image.type = PF_RGBA_32; + r_image.size = r_image.width * r_image.height * 4; + r_image.flags = IMAGE_HAS_ALPHA; + r_image.buffer = NULL; + + g_textures[id] = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE|TF_NEAREST ); + g_iBoundTexture = id; +} + +void GAME_EXPORT VGUI_UploadTextureBlock( int id, int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight ) +{ + if( id <= 0 || id >= VGUI_MAX_TEXTURES || g_textures[id] == 0 || g_textures[id] == tr.whiteTexture ) + { + gEngfuncs.Con_Reportf( S_ERROR "VGUI_UploadTextureBlock: bad texture %i. Ignored\n", id ); + return; + } + + pglTexSubImage2D( GL_TEXTURE_2D, 0, drawX, drawY, blockWidth, blockHeight, GL_RGBA, GL_UNSIGNED_BYTE, rgba ); + g_iBoundTexture = id; +} + +void GAME_EXPORT VGUI_SetupDrawingRect( int *pColor ) +{ + pglEnable( GL_BLEND ); + pglDisable( GL_ALPHA_TEST ); + pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + pglColor4ub( pColor[0], pColor[1], pColor[2], 255 - pColor[3] ); +} + +void GAME_EXPORT VGUI_SetupDrawingText( int *pColor ) +{ + pglEnable( GL_BLEND ); + pglEnable( GL_ALPHA_TEST ); + pglAlphaFunc( GL_GREATER, 0.0f ); + pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + pglColor4ub( pColor[0], pColor[1], pColor[2], 255 - pColor[3] ); +} + +void GAME_EXPORT VGUI_SetupDrawingImage( int *pColor ) +{ + pglEnable( GL_BLEND ); + pglEnable( GL_ALPHA_TEST ); + pglAlphaFunc( GL_GREATER, 0.0f ); + pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + pglColor4ub( pColor[0], pColor[1], pColor[2], 255 - pColor[3] ); +} + +void GAME_EXPORT VGUI_BindTexture( int id ) +{ + if( id > 0 && id < VGUI_MAX_TEXTURES && g_textures[id] ) + { + GL_Bind( XASH_TEXTURE0, g_textures[id] ); + g_iBoundTexture = id; + } + else + { + // NOTE: same as bogus index 2700 in GoldSrc + id = g_iBoundTexture = 1; + GL_Bind( XASH_TEXTURE0, g_textures[id] ); + } +} + +/* +================ +VGUI_GetTextureSizes + +returns wide and tall for currently binded texture +================ +*/ +void GAME_EXPORT VGUI_GetTextureSizes( int *width, int *height ) +{ + gl_texture_t *glt; + int texnum; + + if( g_iBoundTexture ) + texnum = g_textures[g_iBoundTexture]; + else texnum = tr.defaultTexture; + + glt = R_GetTexture( texnum ); + if( width ) *width = glt->srcWidth; + if( height ) *height = glt->srcHeight; +} + +/* +================ +VGUI_EnableTexture + +disable texturemode for fill rectangle +================ +*/ +void GAME_EXPORT VGUI_EnableTexture( qboolean enable ) +{ + if( enable ) pglEnable( GL_TEXTURE_2D ); + else pglDisable( GL_TEXTURE_2D ); +} + +/* +================ +VGUI_DrawQuad + +generic method to fill rectangle +================ +*/ +void GAME_EXPORT VGUI_DrawQuad( const vpoint_t *ul, const vpoint_t *lr ) +{ + int width, height; + float xscale, yscale; + + gEngfuncs.CL_GetScreenInfo( &width, &height ); + + xscale = gpGlobals->width / (float)width; + yscale = gpGlobals->height / (float)height; + + ASSERT( ul != NULL && lr != NULL ); + + pglBegin( GL_QUADS ); + pglTexCoord2f( ul->coord[0], ul->coord[1] ); + pglVertex2f( ul->point[0] * xscale, ul->point[1] * yscale ); + + pglTexCoord2f( lr->coord[0], ul->coord[1] ); + pglVertex2f( lr->point[0] * xscale, ul->point[1] * yscale ); + + pglTexCoord2f( lr->coord[0], lr->coord[1] ); + pglVertex2f( lr->point[0] * xscale, lr->point[1] * yscale ); + + pglTexCoord2f( ul->coord[0], lr->coord[1] ); + pglVertex2f( ul->point[0] * xscale, lr->point[1] * yscale ); + pglEnd(); +} diff --git a/engine/client/gl_warp.c b/ref_gl/gl_warp.c similarity index 92% rename from engine/client/gl_warp.c rename to ref_gl/gl_warp.c index a4ea724d..4399f3b5 100644 --- a/engine/client/gl_warp.c +++ b/ref_gl/gl_warp.c @@ -13,11 +13,9 @@ 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" - #define SKYCLOUDS_QUALITY 12 #define MAX_CLIP_VERTS 128 // skybox clip vertices #define TURBSCALE ( 256.0f / ( M_PI2 )) @@ -80,7 +78,7 @@ static int CheckSkybox( const char *name ) { // build side name sidename = va( "%s%s.%s", name, r_skyBoxSuffix[j], skybox_ext[i] ); - if( FS_FileExists( sidename, false )) + if( gEngfuncs.FS_FileExists( sidename, false )) num_checked_sides++; } @@ -92,7 +90,7 @@ static int CheckSkybox( const char *name ) { // build side name sidename = va( "%s_%s.%s", name, r_skyBoxSuffix[j], skybox_ext[i] ); - if( FS_FileExists( sidename, false )) + if( gEngfuncs.FS_FileExists( sidename, false )) num_checked_sides++; } @@ -163,7 +161,7 @@ void ClipSkyPolygon( int nump, vec3_t vecs, int stage ) int i, j; if( nump > MAX_CLIP_VERTS ) - Host_Error( "ClipSkyPolygon: MAX_CLIP_VERTS\n" ); + gEngfuncs.Host_Error( "ClipSkyPolygon: MAX_CLIP_VERTS\n" ); loc1: if( stage == 6 ) { @@ -311,7 +309,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( ENGINE_GET_PARM( PARM_SKY_SPHERE ) && fa->polys && !tr.fCustomSkybox ) { glpoly_t *p = fa->polys; @@ -355,7 +353,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 ); + tr.fCustomSkybox = false; } /* @@ -412,8 +410,8 @@ R_SetupSky */ void R_SetupSky( const char *skyboxname ) { - char loadname[MAX_QPATH]; - char sidename[MAX_QPATH]; + char loadname[MAX_STRING]; + char sidename[MAX_STRING]; int i, result; if( !COM_CheckString( skyboxname )) @@ -433,14 +431,14 @@ void R_SetupSky( const char *skyboxname ) // to prevent infinite recursion if default skybox was missed if( result == SKYBOX_MISSED && Q_stricmp( loadname, DEFAULT_SKYBOX_PATH )) { - Con_Reportf( S_WARN "missed or incomplete skybox '%s'\n", skyboxname ); + gEngfuncs.Con_Reportf( S_WARN "missed or incomplete skybox '%s'\n", skyboxname ); R_SetupSky( "desert" ); // force to default return; } // release old skybox R_UnloadSkybox(); - Con_DPrintf( "SKY: " ); + gEngfuncs.Con_DPrintf( "SKY: " ); for( i = 0; i < 6; i++ ) { @@ -450,17 +448,17 @@ void R_SetupSky( const char *skyboxname ) tr.skyboxTextures[i] = GL_LoadTexture( sidename, NULL, 0, TF_CLAMP|TF_SKY ); if( !tr.skyboxTextures[i] ) break; - Con_DPrintf( "%s%s%s", skyboxname, r_skyBoxSuffix[i], i != 5 ? ", " : ". " ); + gEngfuncs.Con_DPrintf( "%s%s%s", skyboxname, r_skyBoxSuffix[i], i != 5 ? ", " : ". " ); } if( i == 6 ) { - SetBits( world.flags, FWORLD_CUSTOM_SKYBOX ); - Con_DPrintf( "done\n" ); + tr.fCustomSkybox = true; + gEngfuncs.Con_DPrintf( "done\n" ); return; // loaded } - Con_DPrintf( "^2failed\n" ); + gEngfuncs.Con_DPrintf( "^2failed\n" ); R_UnloadSkybox(); } @@ -503,7 +501,7 @@ void R_CloudTexCoord( vec3_t v, float speed, float *s, float *t ) float length, speedscale; vec3_t dir; - speedscale = cl.time * speed; + speedscale = gpGlobals->time * speed; speedscale -= (int)speedscale & ~127; VectorSubtract( v, RI.vieworg, dir ); @@ -668,19 +666,19 @@ void R_InitSkyClouds( mip_t *mt, texture_t *tx, qboolean custom_palette ) int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6); if( custom_palette ) size += sizeof( short ) + 768; - r_sky = FS_LoadImage( texname, (byte *)mt, size ); + r_sky = gEngfuncs.FS_LoadImage( texname, (byte *)mt, size ); } else { // okay, loading it from wad - r_sky = FS_LoadImage( texname, NULL, 0 ); + r_sky = gEngfuncs.FS_LoadImage( texname, NULL, 0 ); } // make sure what sky image is valid if( !r_sky || !r_sky->palette || r_sky->type != PF_INDEXED_32 || r_sky->height == 0 ) { - Con_Reportf( S_ERROR "R_InitSky: unable to load sky texture %s\n", tx->name ); - if( r_sky ) FS_FreeImage( r_sky ); + gEngfuncs.Con_Reportf( S_ERROR "R_InitSky: unable to load sky texture %s\n", tx->name ); + if( r_sky ) gEngfuncs.FS_FreeImage( r_sky ); return; } @@ -744,7 +742,7 @@ void R_InitSkyClouds( mip_t *mt, texture_t *tx, qboolean custom_palette ) tr.alphaskyTexture = GL_LoadTextureInternal( "alpha_sky", &r_temp, TF_NOMIPMAP ); // clean up - FS_FreeImage( r_sky ); + gEngfuncs.FS_FreeImage( r_sky ); Mem_Free( trans ); } @@ -788,8 +786,8 @@ void EmitWaterPolys( msurface_t *warp, qboolean reverse ) { if( waveHeight ) { - nv = r_turbsin[(int)(cl.time * 160.0f + v[1] + v[0]) & 255] + 8.0f; - nv = (r_turbsin[(int)(v[0] * 5.0f + cl.time * 171.0f - v[1]) & 255] + 8.0f ) * 0.8f + nv; + nv = r_turbsin[(int)(gpGlobals->time * 160.0f + v[1] + v[0]) & 255] + 8.0f; + nv = (r_turbsin[(int)(v[0] * 5.0f + gpGlobals->time * 171.0f - v[1]) & 255] + 8.0f ) * 0.8f + nv; nv = nv * waveHeight + v[2]; } else nv = v[2]; @@ -797,10 +795,10 @@ void EmitWaterPolys( msurface_t *warp, qboolean reverse ) os = v[3]; ot = v[4]; - s = os + r_turbsin[(int)((ot * 0.125f + cl.time) * TURBSCALE) & 255]; + s = os + r_turbsin[(int)((ot * 0.125f + gpGlobals->time) * TURBSCALE) & 255]; s *= ( 1.0f / SUBDIVIDE_SIZE ); - t = ot + r_turbsin[(int)((os * 0.125f + cl.time) * TURBSCALE) & 255]; + t = ot + r_turbsin[(int)((os * 0.125f + gpGlobals->time) * TURBSCALE) & 255]; t *= ( 1.0f / SUBDIVIDE_SIZE ); pglTexCoord2f( s, t ); @@ -819,4 +817,4 @@ void EmitWaterPolys( msurface_t *warp, qboolean reverse ) pglEnd(); GL_SetupFogColorForSurfaces(); -} \ No newline at end of file +} diff --git a/ref_gl/wscript b/ref_gl/wscript new file mode 100644 index 00000000..a4e4b2c6 --- /dev/null +++ b/ref_gl/wscript @@ -0,0 +1,54 @@ +#! /usr/bin/env python +# encoding: utf-8 +# mittorn, 2018 + +from waflib import Logs +import os +from fwgslib import get_subproject_name + +top = '.' + +def options(opt): + # stub + return + +def configure(conf): + # check for dedicated server build + if conf.options.DEDICATED: + return + + if conf.options.SUPPORT_BSP2_FORMAT: + conf.env.append_unique('DEFINES', 'SUPPORT_BSP2_FORMAT') + + conf.env.append_unique('DEFINES', 'REF_DLL') + +def build(bld): + if bld.env.DEDICATED: + return + + bld.load_envs() + name = get_subproject_name(bld) + bld.env = bld.all_envs[name] + + libs = [ 'public', 'M' ] + + source = bld.path.ant_glob(['*.c']) + + includes = ['.', + '../engine', + '../engine/common', + '../engine/server', + '../engine/client', + '../public', + '../common', + '../pm_shared' ] + + bld.shlib( + source = source, + target = name, + features = 'c', + includes = includes, + use = libs, + install_path = bld.env.LIBDIR, + subsystem = bld.env.MSVC_SUBSYSTEM + ) diff --git a/scripts/build_mingw_engine.sh b/scripts/build_mingw_engine.sh index 8c660020..068b7725 100755 --- a/scripts/build_mingw_engine.sh +++ b/scripts/build_mingw_engine.sh @@ -6,8 +6,8 @@ cd $TRAVIS_BUILD_DIR export CC="ccache i686-w64-mingw32-gcc" export CXX="ccache i686-w64-mingw32-g++" -export CFLAGS="-static-libgcc -no-pthread" -export CXXFLAGS="-static-libgcc -static-libstdc++ -no-pthread" +export CFLAGS="-static-libgcc -no-pthread -msse2" # add sse2 to workaround mingw multiple definition of MemoryBarrier bug +export CXXFLAGS="-static-libgcc -static-libstdc++ -no-pthread -msse2" export LDFLAGS="-static-libgcc -static-libstdc++ -no-pthread" export LINKFLAGS="-static-libgcc -static-libstdc++ -no-pthread" export WINRC="i686-w64-mingw32-windres" diff --git a/vgui_support/miniutl b/vgui_support/miniutl index a3c114a8..f68f1ab3 160000 --- a/vgui_support/miniutl +++ b/vgui_support/miniutl @@ -1 +1 @@ -Subproject commit a3c114a8b47574ba351f026fb059a3f26123bd79 +Subproject commit f68f1ab377517328f44202c78fa1fe1adc5a4b52 diff --git a/wscript b/wscript index 98d487be..9e89cd89 100644 --- a/wscript +++ b/wscript @@ -27,8 +27,10 @@ class Subproject: self.singlebin = singlebin SUBDIRS = [ + Subproject('public', dedicated=False), Subproject('engine', dedicated=False), Subproject('game_launch', singlebin=True), + Subproject('ref_gl'), Subproject('mainui'), Subproject('vgui_support'), ] @@ -54,6 +56,9 @@ def options(opt): grp.add_option('--win-style-install', action = 'store_true', dest = 'WIN_INSTALL', default = False, help = 'install like Windows build, ignore prefix, useful for development') + grp.add_option('--enable-bsp2', action = 'store_true', dest = 'SUPPORT_BSP2_FORMAT', default = False, + help = 'build engine and renderers with BSP2 map support(recommended for Quake, breaks compability!)') + grp.add_option('--skip-subprojects', action='store', dest = 'SKIP_SUBDIRS', default=None, help = 'don\'t recurse into specified subprojects. Current subdirs: ' + str(subdirs())) @@ -64,7 +69,7 @@ def options(opt): opt.add_option_group('Cannot find wscript in ' + i.name + '. You probably missed submodule update') else: opt.recurse(i.name) - opt.load('xcompile compiler_cxx compiler_c') + opt.load('xcompile compiler_cxx compiler_c sdl2') if sys.platform == 'win32': opt.load('msvc msvs') @@ -104,7 +109,7 @@ def configure(conf): conf.env.BIT32_MANDATORY = not conf.options.ALLOW64 conf.env.BIT32_ALLOW64 = conf.options.ALLOW64 - conf.load('force_32bit') + conf.load('force_32bit sdl2') if conf.env.DEST_SIZEOF_VOID_P == 4: Logs.info('NOTE: will build engine for 32-bit target') @@ -165,8 +170,8 @@ def configure(conf): # indicate if we are packaging for Linux/BSD - if(not conf.options.WIN_INSTALL and - conf.env.DEST_OS != 'win32' and + if(not conf.options.WIN_INSTALL and + conf.env.DEST_OS != 'win32' and conf.env.DEST_OS != 'darwin'): conf.env.LIBDIR = conf.env.BINDIR = '${PREFIX}/lib/xash3d' else: