Merge branch 'master' into resource
This commit is contained in:
commit
8b30a7631d
222 changed files with 13798 additions and 8154 deletions
13
.gitignore
vendored
13
.gitignore
vendored
|
@ -6,6 +6,7 @@
|
|||
|
||||
# Other
|
||||
*.save
|
||||
|
||||
# Qt Creator for some reason creates *.user.$version files, so exclude it too
|
||||
*.user*
|
||||
*~
|
||||
|
@ -47,7 +48,6 @@ Network Trash Folder
|
|||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
|
||||
### CMake ###
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
|
@ -307,7 +307,18 @@ build-*
|
|||
|
||||
# Android
|
||||
*.apk
|
||||
*.config
|
||||
*.creator
|
||||
*.includes
|
||||
*.files
|
||||
|
||||
# Waf
|
||||
build_current
|
||||
.waf-*
|
||||
waf-*/
|
||||
waf3-*/
|
||||
.lock-waf*
|
||||
*.lastbuildstate
|
||||
*.unsuccessfulbuild
|
||||
__pycache__
|
||||
*.pyc
|
||||
|
|
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
[submodule "mainui"]
|
||||
path = mainui
|
||||
url = https://github.com/FWGS/mainui_cpp
|
||||
[submodule "vgui_support/miniutl"]
|
||||
path = vgui_support/miniutl
|
||||
url = https://github.com/FWGS/miniutl
|
48
.travis.yml
Normal file
48
.travis.yml
Normal file
|
@ -0,0 +1,48 @@
|
|||
language: c
|
||||
cache: ccache
|
||||
compiler: gcc
|
||||
sudo: false
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- mingw-w64-i686-dev
|
||||
- binutils-mingw-w64-i686
|
||||
- gcc-mingw-w64-i686
|
||||
- g++-mingw-w64-i686
|
||||
- p7zip-full
|
||||
- gcc-multilib
|
||||
- g++-multilib
|
||||
- libx11-dev:i386
|
||||
- libxext-dev:i386
|
||||
- x11-utils
|
||||
- libgl1-mesa-dev
|
||||
- libasound-dev
|
||||
- zlib1g:i386
|
||||
- libstdc++6:i386
|
||||
- libfuse2:i386
|
||||
env:
|
||||
global:
|
||||
- SDL_VERSION=2.0.8
|
||||
git:
|
||||
depth: 50
|
||||
submodules: true
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: xenial
|
||||
- os: osx
|
||||
before_script:
|
||||
- sh scripts/travis_common_deps.sh
|
||||
- sh scripts/travis_${TRAVIS_OS_NAME}_deps.sh
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export ANDROID_HOME=$PWD/android-sdk-linux; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools:$PWD/android-ndk; fi
|
||||
script:
|
||||
- sh scripts/build_${TRAVIS_OS_NAME}_engine.sh
|
||||
# - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sh scripts/build_android_engine.sh; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sh scripts/build_mingw_engine.sh; fi
|
||||
after_script:
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ccache --show-stats > ccache_stats.log; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sh scripts/travis-deploy.sh newengine Xash3DFWGS-i386.AppImage xash3d-mingw.7z ccache_stats.log; fi
|
25
common/boneinfo.h
Normal file
25
common/boneinfo.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
boneinfo.h - structure that send delta-compressed bones across network
|
||||
Copyright (C) 2018 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 BONEINFO_H
|
||||
#define BONEINFO_H
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t angles;
|
||||
vec3_t origin;
|
||||
} boneinfo_t;
|
||||
|
||||
#endif//BONEINFO_H
|
|
@ -74,7 +74,7 @@ BRUSH MODELS
|
|||
#define MAX_MAP_MARKSURFACES 524288 // can be increased without problems
|
||||
#else
|
||||
#define MAX_MAP_MODELS 768 // embedded models
|
||||
#define MAX_MAP_ENTSTRING 0x80000 // 512 kB should be enough
|
||||
#define MAX_MAP_ENTSTRING 0x100000 // 1 Mb should be enough
|
||||
#define MAX_MAP_PLANES 65536 // can be increased without problems
|
||||
#define MAX_MAP_NODES 32767 // because negative shorts are leafs
|
||||
#define MAX_MAP_CLIPNODES 32767 // because negative shorts are contents
|
||||
|
@ -117,14 +117,14 @@ BRUSH MODELS
|
|||
#define LUMP_FACEINFO 1 // landscape and lightmap resolution info
|
||||
#define LUMP_CUBEMAPS 2 // cubemap description
|
||||
#define LUMP_VERTNORMALS 3 // phong shaded vertex normals
|
||||
#define LUMP_VERTEX_LIGHT 4 // contain compressed light cubes per empty leafs
|
||||
#define LUMP_LEAF_LIGHTING 4 // store vertex lighting for statics
|
||||
#define LUMP_WORLDLIGHTS 5 // list of all the virtual and real lights (used to relight models in-game)
|
||||
#define LUMP_COLLISION 6 // physics engine collision hull dump
|
||||
#define LUMP_AINODEGRAPH 7 // node graph that stored into the bsp
|
||||
#define LUMP_COLLISION 6 // physics engine collision hull dump (userdata)
|
||||
#define LUMP_AINODEGRAPH 7 // node graph that stored into the bsp (userdata)
|
||||
#define LUMP_SHADOWMAP 8 // contains shadow map for direct light
|
||||
#define LUMP_UNUSED1 9 // one lump reserved for me
|
||||
#define LUMP_UNUSED2 10 // one lump reserved for me
|
||||
#define LUMP_UNUSED3 11 // one lump reserved for me
|
||||
#define LUMP_VERTEX_LIGHT 9 // store vertex lighting for statics
|
||||
#define LUMP_UNUSED0 10 // one lump reserved for me
|
||||
#define LUMP_UNUSED1 11 // one lump reserved for me
|
||||
#define EXTRA_LUMPS 12 // count of the extra lumps
|
||||
|
||||
// texture flags
|
||||
|
@ -132,6 +132,7 @@ BRUSH MODELS
|
|||
#define TEX_WORLD_LUXELS BIT( 1 ) // alternative lightmap matrix will be used (luxels per world units instead of luxels per texels)
|
||||
#define TEX_AXIAL_LUXELS BIT( 2 ) // force world luxels to axial positive scales
|
||||
#define TEX_EXTRA_LIGHTMAP BIT( 3 ) // bsp31 legacy - using 8 texels per luxel instead of 16 texels per luxel
|
||||
#define TEX_SCROLL BIT( 6 ) // Doom special FX
|
||||
|
||||
// ambient sound types
|
||||
enum
|
||||
|
|
|
@ -166,6 +166,7 @@ struct decal_s
|
|||
// Xash3D specific
|
||||
vec3_t position; // location of the decal center in world space.
|
||||
glpoly_t *polys; // precomputed decal vertices
|
||||
int reserved[4]; // just for future expansions or mod-makers
|
||||
};
|
||||
|
||||
typedef struct mleaf_s
|
||||
|
@ -366,7 +367,7 @@ typedef struct player_info_s
|
|||
int userid; // User id on server
|
||||
char userinfo[MAX_INFO_STRING]; // User info string
|
||||
char name[MAX_SCOREBOARDNAME]; // Name (extracted from userinfo)
|
||||
int spectator; // Spectator or not, unused
|
||||
int spectator; // Spectator or not, unused (frags for quake demo playback)
|
||||
|
||||
int ping;
|
||||
int packet_loss;
|
||||
|
|
|
@ -21,7 +21,7 @@ GNU General Public License for more details.
|
|||
/*
|
||||
===================================================================
|
||||
|
||||
SETUP BACKENDS DEFINATIONS
|
||||
SETUP BACKENDS DEFINITIONS
|
||||
|
||||
===================================================================
|
||||
*/
|
||||
|
|
|
@ -51,6 +51,8 @@ typedef struct event_api_s
|
|||
struct pmtrace_s *( *EV_VisTraceLine )( float *start, float *end, int flags );
|
||||
struct physent_s *( *EV_GetVisent )( int idx );
|
||||
int ( *EV_TestLine)( const vec3_t start, const vec3_t end, int flags );
|
||||
void ( *EV_PushTraceBounds)( int hullnum, const float *mins, const float *maxs );
|
||||
void ( *EV_PopTraceBounds)( void );
|
||||
} event_api_t;
|
||||
|
||||
#endif//EVENT_API_H
|
|
@ -17,6 +17,7 @@ GNU General Public License for more details.
|
|||
#define GAMEINFO_H
|
||||
|
||||
#define GFL_NOMODELS (1<<0)
|
||||
#define GFL_NOSKILLS (1<<1)
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
// kill the request hook after receiving the first response
|
||||
#define FNETAPI_MULTIPLE_RESPONSE ( 1<<0 )
|
||||
|
||||
struct net_response_s;
|
||||
typedef void (*net_api_response_func_t) ( struct net_response_s *response );
|
||||
|
||||
#define NET_SUCCESS ( 0 )
|
||||
#define NET_ERROR_TIMEOUT ( 1<<0 )
|
||||
#define NET_ERROR_PROTO_UNSUPPORTED ( 1<<1 )
|
||||
|
@ -58,8 +61,6 @@ typedef struct net_response_s
|
|||
void *response;
|
||||
} net_response_t;
|
||||
|
||||
typedef void (*net_api_response_func_t) ( net_response_t *response );
|
||||
|
||||
typedef struct net_status_s
|
||||
{
|
||||
// Connected to remote server? 1 == yes, 0 otherwise
|
||||
|
@ -83,12 +84,12 @@ typedef struct net_api_s
|
|||
// APIs
|
||||
void (*InitNetworking)( void );
|
||||
void (*Status )( struct net_status_s *status );
|
||||
void (*SendRequest)( int context, int request, int flags, double timeout, netadr_t *remote_address, net_api_response_func_t response );
|
||||
void (*SendRequest)( int context, int request, int flags, double timeout, struct netadr_s *remote_address, net_api_response_func_t response );
|
||||
void (*CancelRequest)( int context );
|
||||
void (*CancelAllRequests)( void );
|
||||
char *(*AdrToString)( netadr_t *a );
|
||||
int ( *CompareAdr)( netadr_t *a, netadr_t *b );
|
||||
int ( *StringToAdr)( char *s, netadr_t *a );
|
||||
char *(*AdrToString)( struct netadr_s *a );
|
||||
int ( *CompareAdr)( struct netadr_s *a, struct netadr_s *b );
|
||||
int ( *StringToAdr)( char *s, struct netadr_s *a );
|
||||
const char *(*ValueForKey)( const char *s, const char *key );
|
||||
void (*RemoveKey)( char *s, const char *key );
|
||||
void (*SetValueForKey)( char *s, const char *key, const char *value, int maxsize );
|
||||
|
|
|
@ -67,7 +67,7 @@ GNU General Public License for more details.
|
|||
#define SERVERDLL "libserver" POSTFIX "." OS_LIB_EXT
|
||||
#define GAMEPATH "/sdcard/xash"
|
||||
#else
|
||||
#define MENUDLL "libxashmenu" ARCH_SUFFIX "." OS_LIB_EXT
|
||||
#define MENUDLL "libmenu" ARCH_SUFFIX "." OS_LIB_EXT
|
||||
#define CLIENTDLL "client" ARCH_SUFFIX "." OS_LIB_EXT
|
||||
#endif
|
||||
|
||||
|
@ -76,6 +76,7 @@ GNU General Public License for more details.
|
|||
// Windows-specific
|
||||
#define __cdecl
|
||||
#define __stdcall
|
||||
|
||||
#define _inline static inline
|
||||
#define O_BINARY 0 // O_BINARY is Windows extension
|
||||
#define O_TEXT 0 // O_TEXT is Windows extension
|
||||
|
@ -118,6 +119,7 @@ GNU General Public License for more details.
|
|||
#define strncasecmp _strnicmp
|
||||
#define open _open
|
||||
#define read _read
|
||||
#define alloca _alloca
|
||||
|
||||
// shut-up compiler warnings
|
||||
#pragma warning(disable : 4244) // MIPS
|
||||
|
|
|
@ -40,7 +40,7 @@ GNU General Public License for more details.
|
|||
#define PARM_TEX_MIPCOUNT 15 // count of mipmaps (0 - autogenerated, 1 - disabled of mipmapping)
|
||||
#define PARM_BSP2_SUPPORTED 16 // tell custom renderer what engine is support BSP2 in this build
|
||||
#define PARM_SKY_SPHERE 17 // sky is quake sphere ?
|
||||
//reserved
|
||||
#define PARAM_GAMEPAUSED 18 // game is paused
|
||||
#define PARM_MAP_HAS_DELUXE 19 // map has deluxedata
|
||||
#define PARM_MAX_ENTITIES 20
|
||||
#define PARM_WIDESCREEN 21
|
||||
|
@ -74,12 +74,13 @@ enum
|
|||
|
||||
typedef enum
|
||||
{
|
||||
TF_COLORMAP = 0, // just for tabulate source
|
||||
TF_NEAREST = (1<<0), // disable texfilter
|
||||
TF_KEEP_SOURCE = (1<<1), // some images keep source
|
||||
TF_NOFLIP_TGA = (1<<2), // Steam background completely ignore tga attribute 0x20
|
||||
TF_EXPAND_SOURCE = (1<<3), // Don't keep source as 8-bit expand to RGBA
|
||||
TF_TEXTURE_2D_ARRAY = (1<<4), // this is 2D texture array (multi-layers)
|
||||
TF_TEXTURE_RECTANGLE= (1<<5), // this is GL_TEXTURE_RECTANGLE
|
||||
TF_ALLOW_EMBOSS = (1<<4), // Allow emboss-mapping for this image
|
||||
TF_RECTANGLE = (1<<5), // this is GL_TEXTURE_RECTANGLE
|
||||
TF_CUBEMAP = (1<<6), // it's cubemap texture
|
||||
TF_DEPTHMAP = (1<<7), // custom texture filter used
|
||||
TF_QUAKEPAL = (1<<8), // image has an quake1 palette
|
||||
|
@ -92,11 +93,11 @@ typedef enum
|
|||
TF_NORMALMAP = (1<<15), // is a normalmap
|
||||
TF_HAS_ALPHA = (1<<16), // image has alpha (used only for GL_CreateTexture)
|
||||
TF_FORCE_COLOR = (1<<17), // force upload monochrome textures as RGB (detail textures)
|
||||
TF_TEXTURE_1D = (1<<18), // this is GL_TEXTURE_1D
|
||||
// reserved
|
||||
TF_BORDER = (1<<19), // zero clamp for projected textures
|
||||
TF_TEXTURE_3D = (1<<20), // this is GL_TEXTURE_3D
|
||||
TF_ATLAS_PAGE = (1<<21), // bit who indicate lightmap page or deluxemap page
|
||||
// reserved
|
||||
TF_ALPHACONTRAST = (1<<22), // special texture mode for A2C
|
||||
// reserved
|
||||
// reserved
|
||||
TF_IMG_UPLOADED = (1<<25), // this is set for first time when called glTexImage, otherwise it will be call glTexSubImage
|
||||
|
@ -185,16 +186,16 @@ typedef struct render_api_s
|
|||
void (*R_EntityRemoveDecals)( struct model_s *mod ); // remove all the decals from specified entity (BSP only)
|
||||
|
||||
// AVIkit support
|
||||
void *(*AVI_LoadVideo)( const char *filename );
|
||||
void *(*AVI_LoadVideo)( const char *filename, qboolean load_audio );
|
||||
int (*AVI_GetVideoInfo)( void *Avi, long *xres, long *yres, float *duration );
|
||||
long (*AVI_GetVideoFrameNumber)( void *Avi, float time );
|
||||
byte *(*AVI_GetVideoFrame)( void *Avi, long frame );
|
||||
void (*AVI_UploadRawFrame)( int texture, int cols, int rows, int width, int height, const byte *data );
|
||||
void (*AVI_FreeVideo)( void *Avi );
|
||||
int (*AVI_IsActive)( void *Avi );
|
||||
void (*AVI_StreamSound)( void *Avi, int entnum, float fvol, float attn, float synctime );
|
||||
void (*AVI_Reserved0)( void ); // for potential interface expansion without broken compatibility
|
||||
void (*AVI_Reserved1)( void );
|
||||
void (*AVI_Reserved2)( void );
|
||||
|
||||
// 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 );
|
||||
|
@ -206,20 +207,20 @@ typedef struct render_api_s
|
|||
void (*GL_TextureTarget)( unsigned int target ); // change texture unit mode without bind texture
|
||||
void (*GL_TexCoordArrayMode)( unsigned int texmode );
|
||||
void* (*GL_GetProcAddress)( const char *name );
|
||||
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 );
|
||||
void (*GL_Reserved2)( void );
|
||||
|
||||
// Misc renderer functions
|
||||
void (*GL_DrawParticles)( const struct ref_viewpass_s *rvp, qboolean trans_pass, float frametime );
|
||||
void (*EnvShot)( const float *vieworg, const char *name, qboolean skyshot, int shotsize ); // store skybox into gfx\env folder
|
||||
int (*SPR_LoadExt)( const char *szPicName, unsigned int texFlags ); // extended version of SPR_Load
|
||||
colorVec (*LightVec)( const float *start, const float *end, float *lightspot );
|
||||
colorVec (*LightVec)( const float *start, const float *end, float *lightspot, float *lightvec );
|
||||
struct mstudiotex_s *( *StudioGetTexture )( struct cl_entity_s *e );
|
||||
const struct ref_overview_s *( *GetOverviewParms )( void );
|
||||
const char *( *GetFileByIndex )( int fileindex );
|
||||
void (*R_Reserved1)( void ); // for potential interface expansion without broken compatibility
|
||||
void (*R_Reserved2)( void );
|
||||
void (*R_Reserved0)( void ); // for potential interface expansion without broken compatibility
|
||||
void (*R_Reserved1)( void );
|
||||
|
||||
// static allocations
|
||||
void *(*pfnMemAlloc)( size_t cb, const char *filename, const int fileline );
|
||||
|
|
|
@ -55,17 +55,6 @@ infotable dlumpinfo_t[dwadinfo_t->numlumps]
|
|||
#define TYP_COLORMAP2 69 // old stuff. build palette from LBM file (not used)
|
||||
#define TYP_QFONT 70 // half-life font (qfont_t)
|
||||
|
||||
// dlumpinfo_t->img_type
|
||||
#define IMG_DIFFUSE 0 // same as default pad1 always equal 0
|
||||
#define IMG_ALPHAMASK 1 // alpha-channel that stored separate as luminance texture
|
||||
#define IMG_NORMALMAP 2 // indexed normalmap
|
||||
#define IMG_GLOSSMAP 3 // luminance or color specularity map
|
||||
#define IMG_GLOSSPOWER 4 // gloss power map (each value is a specular pow)
|
||||
#define IMG_HEIGHTMAP 5 // heightmap (for parallax occlusion mapping or source of normalmap)
|
||||
#define IMG_LUMA 6 // luma or glow texture with self-illuminated parts
|
||||
#define IMG_DECAL_ALPHA 7 // it's a decal texture (last color in palette is base color, and other colors his graduations)
|
||||
#define IMG_DECAL_COLOR 8 // decal without alpha-channel uses base, like 127 127 127 as transparent color
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
|
|
3
contrib/a1batross/xash3d.config
Normal file
3
contrib/a1batross/xash3d.config
Normal file
|
@ -0,0 +1,3 @@
|
|||
// Add predefined macros for your project here. For example:
|
||||
// #define THE_ANSWER 42
|
||||
#define XASH_SDL
|
1
contrib/a1batross/xash3d.creator
Normal file
1
contrib/a1batross/xash3d.creator
Normal file
|
@ -0,0 +1 @@
|
|||
[General]
|
218
contrib/a1batross/xash3d.creator.user
Normal file
218
contrib/a1batross/xash3d.creator.user
Normal file
|
@ -0,0 +1,218 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.5.2, 2018-10-21T21:41:59. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
<value type="QByteArray">{e98eea9b-9ef7-4df9-8f97-1e67893b8b3b}</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||
<value type="int">0</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
||||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||
<value type="QString" key="language">Cpp</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||
<value type="QString" key="language">QmlJS</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
||||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
||||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
||||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
||||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||
<valuemap type="QVariantMap"/>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{cc7c1b7f-457b-4e71-9eeb-5e67c737c51a}</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/a1ba/projects/xash/xash3d-fwgs</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">configure --vgui=vgui-dev --win-style-install --prefix=/home/a1ba/projects/builtXash</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Command">./waf</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Особый</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets"/>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">build -j5 -v</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand">./waf</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
|
||||
<value type="QString">clean</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">true</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand">./waf</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Очистка</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges">
|
||||
<value type="QString">PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">По умолчанию</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">По умолчанию</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">install</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Command">./waf</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Особый</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Установка</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Локальная установка</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
|
||||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
|
||||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
||||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
||||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
||||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
||||
<value type="int">0</value>
|
||||
<value type="int">1</value>
|
||||
<value type="int">2</value>
|
||||
<value type="int">3</value>
|
||||
<value type="int">4</value>
|
||||
<value type="int">5</value>
|
||||
<value type="int">6</value>
|
||||
<value type="int">7</value>
|
||||
<value type="int">8</value>
|
||||
<value type="int">9</value>
|
||||
<value type="int">10</value>
|
||||
<value type="int">11</value>
|
||||
<value type="int">12</value>
|
||||
<value type="int">13</value>
|
||||
<value type="int">14</value>
|
||||
</valuelist>
|
||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes">
|
||||
<value type="QString">LD_LIBRARY_PATH=/home/a1ba/projects/builtXash</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Arguments">-dev 5</value>
|
||||
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">/home/a1ba/projects/builtXash/xash3d</value>
|
||||
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory">/home/a1ba/projects/builtXash</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Запуск /home/a1ba/projects/builtXash/xash3d</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||
<value type="int">1</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||
<value type="int">18</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>Version</variable>
|
||||
<value type="int">18</value>
|
||||
</data>
|
||||
</qtcreator>
|
397
contrib/a1batross/xash3d.files
Normal file
397
contrib/a1batross/xash3d.files
Normal file
|
@ -0,0 +1,397 @@
|
|||
common/backends.h
|
||||
common/beamdef.h
|
||||
common/boneinfo.h
|
||||
common/bspfile.h
|
||||
common/cl_entity.h
|
||||
common/com_model.h
|
||||
common/con_nprint.h
|
||||
common/const.h
|
||||
common/cvardef.h
|
||||
common/defaults.h
|
||||
common/demo_api.h
|
||||
common/dlight.h
|
||||
common/enginefeatures.h
|
||||
common/entity_state.h
|
||||
common/entity_types.h
|
||||
common/event_api.h
|
||||
common/event_args.h
|
||||
common/event_flags.h
|
||||
common/gameinfo.h
|
||||
common/hltv.h
|
||||
common/ivoicetweak.h
|
||||
common/kbutton.h
|
||||
common/lightstyle.h
|
||||
common/mathlib.h
|
||||
common/net_api.h
|
||||
common/netadr.h
|
||||
common/particledef.h
|
||||
common/pmtrace.h
|
||||
common/port.h
|
||||
common/qfont.h
|
||||
common/r_efx.h
|
||||
common/r_studioint.h
|
||||
common/ref_params.h
|
||||
common/render_api.h
|
||||
common/screenfade.h
|
||||
common/studio_event.h
|
||||
common/triangleapi.h
|
||||
common/usercmd.h
|
||||
common/wadfile.h
|
||||
common/weaponinfo.h
|
||||
common/wrect.h
|
||||
common/xash3d_types.h
|
||||
engine/alias.h
|
||||
engine/anorms.h
|
||||
engine/cdll_exp.h
|
||||
engine/cdll_int.h
|
||||
engine/client/avi/avi.h
|
||||
engine/client/avi/avi_stub.c
|
||||
engine/client/avi/avi_win.c
|
||||
engine/client/cl_cmds.c
|
||||
engine/client/cl_custom.c
|
||||
engine/client/cl_debug.c
|
||||
engine/client/cl_demo.c
|
||||
engine/client/cl_events.c
|
||||
engine/client/cl_frame.c
|
||||
engine/client/cl_game.c
|
||||
engine/client/cl_gameui.c
|
||||
engine/client/cl_main.c
|
||||
engine/client/cl_mobile.c
|
||||
engine/client/cl_netgraph.c
|
||||
engine/client/cl_parse.c
|
||||
engine/client/cl_pmove.c
|
||||
engine/client/cl_qparse.c
|
||||
engine/client/cl_remap.c
|
||||
engine/client/cl_scrn.c
|
||||
engine/client/cl_tent.c
|
||||
engine/client/cl_tent.h
|
||||
engine/client/cl_video.c
|
||||
engine/client/cl_view.c
|
||||
engine/client/client.h
|
||||
engine/client/console.c
|
||||
engine/client/gl_alias.c
|
||||
engine/client/gl_backend.c
|
||||
engine/client/gl_beams.c
|
||||
engine/client/gl_cull.c
|
||||
engine/client/gl_decals.c
|
||||
engine/client/gl_draw.c
|
||||
engine/client/gl_export.h
|
||||
engine/client/gl_frustum.c
|
||||
engine/client/gl_frustum.h
|
||||
engine/client/gl_image.c
|
||||
engine/client/gl_local.h
|
||||
engine/client/gl_refrag.c
|
||||
engine/client/gl_rlight.c
|
||||
engine/client/gl_rmain.c
|
||||
engine/client/gl_rmath.c
|
||||
engine/client/gl_rmisc.c
|
||||
engine/client/gl_rpart.c
|
||||
engine/client/gl_rsurf.c
|
||||
engine/client/gl_sprite.c
|
||||
engine/client/gl_studio.c
|
||||
engine/client/gl_warp.c
|
||||
engine/client/in_evdev.c
|
||||
engine/client/in_joy.c
|
||||
engine/client/in_touch.c
|
||||
engine/client/input.c
|
||||
engine/client/input.h
|
||||
engine/client/keys.c
|
||||
engine/client/mod_dbghulls.c
|
||||
engine/client/s_dsp.c
|
||||
engine/client/s_load.c
|
||||
engine/client/s_main.c
|
||||
engine/client/s_mix.c
|
||||
engine/client/s_mouth.c
|
||||
engine/client/s_stream.c
|
||||
engine/client/s_utils.c
|
||||
engine/client/s_vox.c
|
||||
engine/client/sound.h
|
||||
engine/client/titles.c
|
||||
engine/client/vgui/vgui_draw.c
|
||||
engine/client/vgui/vgui_draw.h
|
||||
engine/client/vgui/vgui_main.h
|
||||
engine/client/vid_common.c
|
||||
engine/client/vid_common.h
|
||||
engine/client/vox.h
|
||||
engine/common/base_cmd.c
|
||||
engine/common/base_cmd.h
|
||||
engine/common/build.c
|
||||
engine/common/cfgscript.c
|
||||
engine/common/cmd.c
|
||||
engine/common/com_strings.h
|
||||
engine/common/common.c
|
||||
engine/common/common.h
|
||||
engine/common/con_utils.c
|
||||
engine/common/crashhandler.c
|
||||
engine/common/crclib.c
|
||||
engine/common/crtlib.c
|
||||
engine/common/crtlib.h
|
||||
engine/common/custom.c
|
||||
engine/common/cvar.c
|
||||
engine/common/cvar.h
|
||||
engine/common/dedicated.c
|
||||
engine/common/filesystem.c
|
||||
engine/common/filesystem.h
|
||||
engine/common/gamma.c
|
||||
engine/common/host.c
|
||||
engine/common/host_state.c
|
||||
engine/common/hpak.c
|
||||
engine/common/identification.c
|
||||
engine/common/imagelib/imagelib.h
|
||||
engine/common/imagelib/img_bmp.c
|
||||
engine/common/imagelib/img_dds.c
|
||||
engine/common/imagelib/img_main.c
|
||||
engine/common/imagelib/img_quant.c
|
||||
engine/common/imagelib/img_tga.c
|
||||
engine/common/imagelib/img_utils.c
|
||||
engine/common/imagelib/img_wad.c
|
||||
engine/common/infostring.c
|
||||
engine/common/launcher.c
|
||||
engine/common/lib_common.c
|
||||
engine/common/library.h
|
||||
engine/common/masterlist.c
|
||||
engine/common/mathlib.c
|
||||
engine/common/mathlib.h
|
||||
engine/common/matrixlib.c
|
||||
engine/common/mod_bmodel.c
|
||||
engine/common/mod_local.h
|
||||
engine/common/mod_studio.c
|
||||
engine/common/model.c
|
||||
engine/common/net_buffer.c
|
||||
engine/common/net_buffer.h
|
||||
engine/common/net_chan.c
|
||||
engine/common/net_encode.c
|
||||
engine/common/net_encode.h
|
||||
engine/common/net_ws.c
|
||||
engine/common/net_ws.h
|
||||
engine/common/netchan.h
|
||||
engine/common/pm_debug.c
|
||||
engine/common/pm_local.h
|
||||
engine/common/pm_surface.c
|
||||
engine/common/pm_trace.c
|
||||
engine/common/protocol.h
|
||||
engine/common/sequence.c
|
||||
engine/common/soundlib/libmpg/dct36.c
|
||||
engine/common/soundlib/libmpg/dct64.c
|
||||
engine/common/soundlib/libmpg/fmt123.h
|
||||
engine/common/soundlib/libmpg/format.c
|
||||
engine/common/soundlib/libmpg/frame.c
|
||||
engine/common/soundlib/libmpg/frame.h
|
||||
engine/common/soundlib/libmpg/getbits.h
|
||||
engine/common/soundlib/libmpg/huffman.h
|
||||
engine/common/soundlib/libmpg/index.c
|
||||
engine/common/soundlib/libmpg/index.h
|
||||
engine/common/soundlib/libmpg/layer3.c
|
||||
engine/common/soundlib/libmpg/libmpg.c
|
||||
engine/common/soundlib/libmpg/libmpg.h
|
||||
engine/common/soundlib/libmpg/mpeghead.h
|
||||
engine/common/soundlib/libmpg/mpg123.c
|
||||
engine/common/soundlib/libmpg/mpg123.h
|
||||
engine/common/soundlib/libmpg/parse.c
|
||||
engine/common/soundlib/libmpg/reader.c
|
||||
engine/common/soundlib/libmpg/reader.h
|
||||
engine/common/soundlib/libmpg/sample.h
|
||||
engine/common/soundlib/libmpg/synth.c
|
||||
engine/common/soundlib/libmpg/synth.h
|
||||
engine/common/soundlib/libmpg/tabinit.c
|
||||
engine/common/soundlib/snd_main.c
|
||||
engine/common/soundlib/snd_mp3.c
|
||||
engine/common/soundlib/snd_utils.c
|
||||
engine/common/soundlib/snd_wav.c
|
||||
engine/common/soundlib/soundlib.h
|
||||
engine/common/sys_con.c
|
||||
engine/common/system.c
|
||||
engine/common/system.h
|
||||
engine/common/world.c
|
||||
engine/common/world.h
|
||||
engine/common/zone.c
|
||||
engine/custom.h
|
||||
engine/customentity.h
|
||||
engine/edict.h
|
||||
engine/eiface.h
|
||||
engine/keydefs.h
|
||||
engine/menu_int.h
|
||||
engine/mobility_int.h
|
||||
engine/physint.h
|
||||
engine/platform/android/lib_android.c
|
||||
engine/platform/android/lib_android.h
|
||||
engine/platform/apple/lib_ios.c
|
||||
engine/platform/apple/lib_ios.h
|
||||
engine/platform/emscripten/lib_em.c
|
||||
engine/platform/emscripten/lib_em.h
|
||||
engine/platform/platform.h
|
||||
engine/platform/posix/lib_posix.c
|
||||
engine/platform/sdl/events.c
|
||||
engine/platform/sdl/events.h
|
||||
engine/platform/sdl/in_sdl.c
|
||||
engine/platform/sdl/s_sdl.c
|
||||
engine/platform/sdl/vid_sdl.c
|
||||
engine/platform/win32/con_win.c
|
||||
engine/platform/win32/lib_win.c
|
||||
engine/progdefs.h
|
||||
engine/sequence.h
|
||||
engine/server/server.h
|
||||
engine/server/sv_client.c
|
||||
engine/server/sv_cmds.c
|
||||
engine/server/sv_custom.c
|
||||
engine/server/sv_frame.c
|
||||
engine/server/sv_game.c
|
||||
engine/server/sv_init.c
|
||||
engine/server/sv_log.c
|
||||
engine/server/sv_main.c
|
||||
engine/server/sv_move.c
|
||||
engine/server/sv_phys.c
|
||||
engine/server/sv_pmove.c
|
||||
engine/server/sv_save.c
|
||||
engine/server/sv_world.c
|
||||
engine/shake.h
|
||||
engine/sprite.h
|
||||
engine/studio.h
|
||||
engine/vgui_api.h
|
||||
engine/warpsin.h
|
||||
engine/wscript
|
||||
game_launch/game.cpp
|
||||
game_launch/game.rc
|
||||
game_launch/wscript
|
||||
mainui/Android.mk
|
||||
mainui/BMPUtils.h
|
||||
mainui/BaseMenu.cpp
|
||||
mainui/BaseMenu.h
|
||||
mainui/Btns.cpp
|
||||
mainui/BtnsBMPTable.h
|
||||
mainui/CFGScript.cpp
|
||||
mainui/CFGScript.h
|
||||
mainui/Color.cpp
|
||||
mainui/Color.h
|
||||
mainui/Coord.h
|
||||
mainui/EngineCallback.cpp
|
||||
mainui/EventSystem.cpp
|
||||
mainui/EventSystem.h
|
||||
mainui/MenuStrings.cpp
|
||||
mainui/MenuStrings.h
|
||||
mainui/Primitive.h
|
||||
mainui/Scissor.cpp
|
||||
mainui/Scissor.h
|
||||
mainui/Utils.cpp
|
||||
mainui/Utils.h
|
||||
mainui/controls/Action.cpp
|
||||
mainui/controls/Action.h
|
||||
mainui/controls/BackgroundBitmap.cpp
|
||||
mainui/controls/BackgroundBitmap.h
|
||||
mainui/controls/BaseClientWindow.cpp
|
||||
mainui/controls/BaseClientWindow.h
|
||||
mainui/controls/BaseItem.cpp
|
||||
mainui/controls/BaseItem.h
|
||||
mainui/controls/BaseWindow.cpp
|
||||
mainui/controls/BaseWindow.h
|
||||
mainui/controls/Bitmap.cpp
|
||||
mainui/controls/Bitmap.h
|
||||
mainui/controls/CheckBox.cpp
|
||||
mainui/controls/CheckBox.h
|
||||
mainui/controls/Editable.cpp
|
||||
mainui/controls/Editable.h
|
||||
mainui/controls/Field.cpp
|
||||
mainui/controls/Field.h
|
||||
mainui/controls/Framework.cpp
|
||||
mainui/controls/Framework.h
|
||||
mainui/controls/ItemsHolder.cpp
|
||||
mainui/controls/ItemsHolder.h
|
||||
mainui/controls/MessageBox.cpp
|
||||
mainui/controls/MessageBox.h
|
||||
mainui/controls/PicButton.cpp
|
||||
mainui/controls/PicButton.h
|
||||
mainui/controls/PlayerModelView.cpp
|
||||
mainui/controls/PlayerModelView.h
|
||||
mainui/controls/ProgressBar.cpp
|
||||
mainui/controls/ProgressBar.h
|
||||
mainui/controls/ScrollView.cpp
|
||||
mainui/controls/ScrollView.h
|
||||
mainui/controls/Slider.cpp
|
||||
mainui/controls/Slider.h
|
||||
mainui/controls/SpinControl.cpp
|
||||
mainui/controls/SpinControl.h
|
||||
mainui/controls/Switch.cpp
|
||||
mainui/controls/Switch.h
|
||||
mainui/controls/TabView.cpp
|
||||
mainui/controls/TabView.h
|
||||
mainui/controls/Table.cpp
|
||||
mainui/controls/Table.h
|
||||
mainui/controls/YesNoMessageBox.cpp
|
||||
mainui/controls/YesNoMessageBox.h
|
||||
mainui/enginecallback_menu.h
|
||||
mainui/extdll_menu.h
|
||||
mainui/font/BaseFontBackend.cpp
|
||||
mainui/font/BaseFontBackend.h
|
||||
mainui/font/BitmapFont.cpp
|
||||
mainui/font/BitmapFont.h
|
||||
mainui/font/FontManager.cpp
|
||||
mainui/font/FontManager.h
|
||||
mainui/font/FontRenderer.h
|
||||
mainui/font/FreeTypeFont.cpp
|
||||
mainui/font/FreeTypeFont.h
|
||||
mainui/font/StbFont.cpp
|
||||
mainui/font/StbFont.h
|
||||
mainui/font/WinAPIFont.cpp
|
||||
mainui/font/WinAPIFont.h
|
||||
mainui/font/stb_truetype.h
|
||||
mainui/legacy/menu_playdemo.cpp
|
||||
mainui/legacy/menu_playrec.cpp
|
||||
mainui/legacy/menu_recdemo.cpp
|
||||
mainui/menufont.h
|
||||
mainui/menus/AdvancedControls.cpp
|
||||
mainui/menus/Audio.cpp
|
||||
mainui/menus/Configuration.cpp
|
||||
mainui/menus/ConnectionProgress.cpp
|
||||
mainui/menus/ConnectionProgress.h
|
||||
mainui/menus/ConnectionWarning.cpp
|
||||
mainui/menus/ConnectionWarning.h
|
||||
mainui/menus/Controls.cpp
|
||||
mainui/menus/CreateGame.cpp
|
||||
mainui/menus/Credits.cpp
|
||||
mainui/menus/CustomGame.cpp
|
||||
mainui/menus/FileDialog.cpp
|
||||
mainui/menus/GameOptions.cpp
|
||||
mainui/menus/Gamepad.cpp
|
||||
mainui/menus/InputDevices.cpp
|
||||
mainui/menus/LoadGame.cpp
|
||||
mainui/menus/Main.cpp
|
||||
mainui/menus/Multiplayer.cpp
|
||||
mainui/menus/NewGame.cpp
|
||||
mainui/menus/PlayerIntroduceDialog.cpp
|
||||
mainui/menus/PlayerIntroduceDialog.h
|
||||
mainui/menus/PlayerSetup.cpp
|
||||
mainui/menus/SaveLoad.cpp
|
||||
mainui/menus/ServerBrowser.cpp
|
||||
mainui/menus/Touch.cpp
|
||||
mainui/menus/TouchButtons.cpp
|
||||
mainui/menus/TouchEdit.cpp
|
||||
mainui/menus/TouchOptions.cpp
|
||||
mainui/menus/Video.cpp
|
||||
mainui/menus/VideoModes.cpp
|
||||
mainui/menus/VideoOptions.cpp
|
||||
mainui/menus/Zoo.cpp
|
||||
mainui/menus/dynamic/ScriptMenu.cpp
|
||||
mainui/model/BaseArrayModel.h
|
||||
mainui/model/BaseModel.h
|
||||
mainui/model/StringArrayModel.h
|
||||
mainui/udll_int.cpp
|
||||
mainui/utl/unicode_strtools.cpp
|
||||
mainui/utl/unicode_strtools.h
|
||||
mainui/utl/utlmemory.h
|
||||
mainui/utl/utlrbtree.h
|
||||
mainui/utl/utlvector.h
|
||||
mainui/wscript
|
||||
pm_shared/pm_defs.h
|
||||
pm_shared/pm_info.h
|
||||
pm_shared/pm_movevars.h
|
||||
vgui_support/utlmemory.h
|
||||
vgui_support/utlrbtree.h
|
||||
vgui_support/utlvector.h
|
||||
vgui_support/vgui_clip.cpp
|
||||
vgui_support/vgui_font.cpp
|
||||
vgui_support/vgui_input.cpp
|
||||
vgui_support/vgui_int.cpp
|
||||
vgui_support/vgui_main.h
|
||||
vgui_support/vgui_surf.cpp
|
||||
vgui_support/wscript
|
||||
wscript
|
19
contrib/a1batross/xash3d.includes
Normal file
19
contrib/a1batross/xash3d.includes
Normal file
|
@ -0,0 +1,19 @@
|
|||
engine
|
||||
engine/client
|
||||
engine/client/avi
|
||||
engine/client/vgui
|
||||
engine/common
|
||||
engine/common/imagelib
|
||||
engine/common/soundlib
|
||||
engine/common/soundlib/libmpg
|
||||
engine/server
|
||||
mainui
|
||||
mainui/controls
|
||||
mainui/font
|
||||
mainui/menus
|
||||
mainui/model
|
||||
mainui/utl
|
||||
pm_shared
|
||||
vgui_support
|
||||
common
|
||||
/usr/include/SDL2
|
|
@ -15,17 +15,13 @@ GNU General Public License for more details.
|
|||
#ifndef CDLL_EXP_H
|
||||
#define CDLL_EXP_H
|
||||
|
||||
typedef struct r_studio_interface_s r_studio_interface_t;
|
||||
typedef struct engine_studio_api_s engine_studio_api_t;
|
||||
typedef struct mstudioevent_s mstudioevent_t;
|
||||
typedef struct local_state_s local_state_t;
|
||||
typedef struct playermove_s playermove_t;
|
||||
typedef struct tempent_s tempent_t;
|
||||
typedef struct physent_s physent_t;
|
||||
typedef struct pmtrace_s pmtrace_t;
|
||||
typedef struct usercmd_s usercmd_t;
|
||||
typedef struct netadr_s netadr_t;
|
||||
|
||||
struct tempent_s;
|
||||
struct usercmd_s;
|
||||
struct physent_s;
|
||||
struct playermove_s;
|
||||
struct mstudioevent_s;
|
||||
struct engine_studio_api_s;
|
||||
struct r_studio_interface_s;
|
||||
|
||||
// NOTE: ordering is important!
|
||||
typedef struct cldll_func_s
|
||||
|
@ -36,15 +32,15 @@ typedef struct cldll_func_s
|
|||
int (*pfnRedraw)( float flTime, int intermission );
|
||||
int (*pfnUpdateClientData)( client_data_t *cdata, float flTime );
|
||||
void (*pfnReset)( void );
|
||||
void (*pfnPlayerMove)( playermove_t *ppmove, int server );
|
||||
void (*pfnPlayerMoveInit)( playermove_t *ppmove );
|
||||
void (*pfnPlayerMove)( struct playermove_s *ppmove, int server );
|
||||
void (*pfnPlayerMoveInit)( struct playermove_s *ppmove );
|
||||
char (*pfnPlayerMoveTexture)( char *name );
|
||||
void (*IN_ActivateMouse)( void );
|
||||
void (*IN_DeactivateMouse)( void );
|
||||
void (*IN_MouseEvent)( int mstate );
|
||||
void (*IN_ClearStates)( void );
|
||||
void (*IN_Accumulate)( void );
|
||||
void (*CL_CreateMove)( float frametime, usercmd_t *cmd, int active );
|
||||
void (*CL_CreateMove)( float frametime, struct usercmd_s *cmd, int active );
|
||||
int (*CL_IsThirdPerson)( void );
|
||||
void (*CL_CameraOffset)( float *ofs ); // unused
|
||||
void *(*KB_Find)( const char *name );
|
||||
|
@ -54,26 +50,26 @@ typedef struct cldll_func_s
|
|||
void (*pfnCreateEntities)( void );
|
||||
void (*pfnDrawNormalTriangles)( void );
|
||||
void (*pfnDrawTransparentTriangles)( void );
|
||||
void (*pfnStudioEvent)( const mstudioevent_t *event, const cl_entity_t *entity );
|
||||
void (*pfnPostRunCmd)( local_state_t *from, local_state_t *to, usercmd_t *cmd, int runfuncs, double time, unsigned int random_seed );
|
||||
void (*pfnStudioEvent)( const struct mstudioevent_s *event, const cl_entity_t *entity );
|
||||
void (*pfnPostRunCmd)( struct local_state_s *from, struct local_state_s *to, usercmd_t *cmd, int runfuncs, double time, unsigned int random_seed );
|
||||
void (*pfnShutdown)( void );
|
||||
void (*pfnTxferLocalOverrides)( entity_state_t *state, const clientdata_t *client );
|
||||
void (*pfnProcessPlayerState)( entity_state_t *dst, const entity_state_t *src );
|
||||
void (*pfnTxferPredictionData)( entity_state_t *ps, const entity_state_t *pps, clientdata_t *pcd, const clientdata_t *ppcd, weapon_data_t *wd, const weapon_data_t *pwd );
|
||||
void (*pfnDemo_ReadBuffer)( int size, byte *buffer );
|
||||
int (*pfnConnectionlessPacket)( const netadr_t *net_from, const char *args, char *buffer, int *size );
|
||||
int (*pfnConnectionlessPacket)( const struct netadr_s *net_from, const char *args, char *buffer, int *size );
|
||||
int (*pfnGetHullBounds)( int hullnumber, float *mins, float *maxs );
|
||||
void (*pfnFrame)( double time );
|
||||
int (*pfnKey_Event)( int eventcode, int keynum, const char *pszCurrentBinding );
|
||||
void (*pfnTempEntUpdate)( double frametime, double client_time, double cl_gravity, tempent_t **ppTempEntFree, tempent_t **ppTempEntActive, int ( *Callback_AddVisibleEntity )( cl_entity_t *pEntity ), void ( *Callback_TempEntPlaySound )( tempent_t *pTemp, float damp ));
|
||||
void (*pfnTempEntUpdate)( double frametime, double client_time, double cl_gravity, struct tempent_s **ppTempEntFree, struct tempent_s **ppTempEntActive, int ( *Callback_AddVisibleEntity )( cl_entity_t *pEntity ), void ( *Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ));
|
||||
cl_entity_t *(*pfnGetUserEntity)( int index );
|
||||
void (*pfnVoiceStatus)( int entindex, qboolean bTalking );
|
||||
void (*pfnDirectorMessage)( int iSize, void *pbuf );
|
||||
int (*pfnGetStudioModelInterface)( int version, r_studio_interface_t **ppinterface, engine_studio_api_t *pstudio );
|
||||
int (*pfnGetStudioModelInterface)( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio );
|
||||
void (*pfnChatInputPosition)( int *x, int *y );
|
||||
// Xash3D extension
|
||||
int (*pfnGetRenderInterface)( int version, render_api_t *renderfuncs, render_interface_t *callback );
|
||||
void (*pfnClipMoveToEntity)( physent_t *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, pmtrace_t *tr );
|
||||
void (*pfnClipMoveToEntity)( struct physent_s *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, struct pmtrace_s *tr );
|
||||
// Xash3D FWGS extension
|
||||
int (*pfnTouchEvent)( int type, int fingerID, float x, float y, float dx, float dy );
|
||||
void (*pfnMoveEvent)( float forwardmove, float sidemove );
|
||||
|
|
|
@ -212,6 +212,7 @@ typedef struct cl_enginefuncs_s
|
|||
float (*pfnRandomFloat)( float flLow, float flHigh );
|
||||
int (*pfnRandomLong)( int lLow, int lHigh );
|
||||
void (*pfnHookEvent)( const char *name, void ( *pfnEvent )( struct event_args_s *args ));
|
||||
|
||||
int (*Con_IsVisible) ();
|
||||
const char *(*pfnGetGameDirectory)( void );
|
||||
struct cvar_s *(*pfnGetCvarPointer)( const char *szName );
|
||||
|
|
|
@ -26,7 +26,8 @@ qboolean AVI_GetAudioInfo( movie_state_t *Avi, wavdata_t *snd_info );
|
|||
long AVI_GetAudioChunk( movie_state_t *Avi, char *audiodata, long offset, long length );
|
||||
void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audio, int quiet );
|
||||
movie_state_t *AVI_LoadVideo( const char *filename, qboolean load_audio );
|
||||
movie_state_t *AVI_LoadVideoNoSound( const char *filename );
|
||||
long AVI_TimeToSoundPosition( movie_state_t *Avi, long time );
|
||||
long AVI_GetVideoFrameCount( movie_state_t *Avi );
|
||||
void AVI_CloseVideo( movie_state_t *Avi );
|
||||
qboolean AVI_IsActive( movie_state_t *Avi );
|
||||
void AVI_FreeVideo( movie_state_t *Avi );
|
||||
|
|
|
@ -51,9 +51,14 @@ movie_state_t *AVI_LoadVideo( const char *filename, qboolean load_audio )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
movie_state_t *AVI_LoadVideoNoSound( const char *filename )
|
||||
long AVI_TimeToSoundPosition( movie_state_t *Avi, long time )
|
||||
{
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
long AVI_GetVideoFrameCount( movie_state_t *Avi )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AVI_CloseVideo( movie_state_t *Avi )
|
||||
|
|
|
@ -59,6 +59,7 @@ dll_info_t msacm_dll = { "msacm32.dll", msacm_funcs, false };
|
|||
static int (_stdcall *pAVIStreamInfo)( PAVISTREAM pavi, AVISTREAMINFO *psi, LONG lSize );
|
||||
static int (_stdcall *pAVIStreamRead)( PAVISTREAM pavi, LONG lStart, LONG lSamples, void *lpBuffer, LONG cbBuffer, LONG *plBytes, LONG *plSamples );
|
||||
static PGETFRAME (_stdcall *pAVIStreamGetFrameOpen)( PAVISTREAM pavi, LPBITMAPINFOHEADER lpbiWanted );
|
||||
static long (_stdcall *pAVIStreamTimeToSample)( PAVISTREAM pavi, LONG lTime );
|
||||
static void* (_stdcall *pAVIStreamGetFrame)( PGETFRAME pg, LONG lPos );
|
||||
static int (_stdcall *pAVIStreamGetFrameClose)( PGETFRAME pg );
|
||||
static dword (_stdcall *pAVIStreamRelease)( PAVISTREAM pavi );
|
||||
|
@ -85,6 +86,7 @@ static dllfunc_t avifile_funcs[] =
|
|||
{ "AVIStreamReadFormat", (void **) &pAVIStreamReadFormat },
|
||||
{ "AVIStreamRelease", (void **) &pAVIStreamRelease },
|
||||
{ "AVIStreamStart", (void **) &pAVIStreamStart },
|
||||
{ "AVIStreamTimeToSample", (void **) &pAVIStreamTimeToSample },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -142,7 +144,8 @@ qboolean AVI_ACMConvertAudio( movie_state_t *Avi )
|
|||
// WMA codecs, both versions - they simply don't work.
|
||||
if( Avi->audio_header->wFormatTag == 0x160 || Avi->audio_header->wFormatTag == 0x161 )
|
||||
{
|
||||
if( !Avi->quiet ) MsgDev( D_ERROR, "ACM does not support this audio codec.\n" );
|
||||
if( !Avi->quiet )
|
||||
Con_Reportf( S_ERROR "ACM does not support this audio codec.\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -151,7 +154,8 @@ qboolean AVI_ACMConvertAudio( movie_state_t *Avi )
|
|||
|
||||
if( Avi->audio_header_size < sizeof( WAVEFORMATEX ))
|
||||
{
|
||||
if( !Avi->quiet ) MsgDev( D_ERROR, "ACM failed to open conversion stream.\n" );
|
||||
if( !Avi->quiet )
|
||||
Con_Reportf( S_ERROR "ACM failed to open conversion stream.\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -181,7 +185,8 @@ qboolean AVI_ACMConvertAudio( movie_state_t *Avi )
|
|||
|
||||
if( pacmStreamOpen( &Avi->cpa_conversion_stream, NULL, sh, dh, NULL, 0, 0, 0 ) != MMSYSERR_NOERROR )
|
||||
{
|
||||
if( !Avi->quiet ) MsgDev( D_ERROR, "ACM failed to open conversion stream.\n" );
|
||||
if( !Avi->quiet )
|
||||
Con_Reportf( S_ERROR "ACM failed to open conversion stream.\n" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -201,13 +206,14 @@ qboolean AVI_ACMConvertAudio( movie_state_t *Avi )
|
|||
// get the size of the output buffer for streaming the compressed audio
|
||||
if( pacmStreamSize( Avi->cpa_conversion_stream, Avi->cpa_blockalign, &dest_length, ACM_STREAMSIZEF_SOURCE ) != MMSYSERR_NOERROR )
|
||||
{
|
||||
if( !Avi->quiet ) MsgDev( D_ERROR, "Couldn't get ACM conversion stream size.\n" );
|
||||
if( !Avi->quiet )
|
||||
Con_Reportf( S_ERROR "Couldn't get ACM conversion stream size.\n" );
|
||||
pacmStreamClose( Avi->cpa_conversion_stream, 0 );
|
||||
return false;
|
||||
}
|
||||
|
||||
Avi->cpa_srcbuffer = (byte *)Mem_Alloc( cls.mempool, Avi->cpa_blockalign );
|
||||
Avi->cpa_dstbuffer = (byte *)Mem_Alloc( cls.mempool, dest_length ); // maintained buffer for raw data
|
||||
Avi->cpa_srcbuffer = (byte *)Mem_Malloc( cls.mempool, Avi->cpa_blockalign );
|
||||
Avi->cpa_dstbuffer = (byte *)Mem_Malloc( cls.mempool, dest_length ); // maintained buffer for raw data
|
||||
|
||||
// prep the headers!
|
||||
Avi->cpa_conversion_header.cbStruct = sizeof( ACMSTREAMHEADER );
|
||||
|
@ -224,7 +230,8 @@ qboolean AVI_ACMConvertAudio( movie_state_t *Avi )
|
|||
|
||||
if( pacmStreamPrepareHeader( Avi->cpa_conversion_stream, &Avi->cpa_conversion_header, 0 ) != MMSYSERR_NOERROR )
|
||||
{
|
||||
if( !Avi->quiet ) MsgDev( D_ERROR, "couldn't prep headers.\n" );
|
||||
if( !Avi->quiet )
|
||||
Con_Reportf( S_ERROR "couldn't prepare stream headers.\n" );
|
||||
pacmStreamClose( Avi->cpa_conversion_stream, 0 );
|
||||
return false;
|
||||
}
|
||||
|
@ -271,6 +278,23 @@ long AVI_GetVideoFrameNumber( movie_state_t *Avi, float time )
|
|||
return (time * Avi->video_fps);
|
||||
}
|
||||
|
||||
long AVI_GetVideoFrameCount( movie_state_t *Avi )
|
||||
{
|
||||
if( !Avi->active )
|
||||
return 0;
|
||||
|
||||
return Avi->video_frames;
|
||||
}
|
||||
|
||||
long AVI_TimeToSoundPosition( movie_state_t *Avi, long time )
|
||||
{
|
||||
if( !Avi->active || !Avi->audio_stream )
|
||||
return 0;
|
||||
|
||||
// UNDONE: what about compressed audio?
|
||||
return pAVIStreamTimeToSample( Avi->audio_stream, time ) * Avi->audio_bytes_per_sample;
|
||||
}
|
||||
|
||||
// gets the raw frame data
|
||||
byte *AVI_GetVideoFrame( movie_state_t *Avi, long frame )
|
||||
{
|
||||
|
@ -378,8 +402,11 @@ long AVI_GetAudioChunk( movie_state_t *Avi, char *audiodata, long offset, long l
|
|||
}
|
||||
else
|
||||
{
|
||||
// we out of soundtrack, just zeroing buffer
|
||||
for( i = 0; i < length; i++ )
|
||||
audiodata[i] = 0;
|
||||
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -482,20 +509,25 @@ void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audi
|
|||
switch( hr )
|
||||
{
|
||||
case AVIERR_BADFORMAT:
|
||||
if( !Avi->quiet ) MsgDev( D_ERROR, "corrupt file or unknown format.\n" );
|
||||
if( !Avi->quiet )
|
||||
Con_DPrintf( S_ERROR "corrupt file or unknown format.\n" );
|
||||
break;
|
||||
case AVIERR_MEMORY:
|
||||
if( !Avi->quiet ) MsgDev( D_ERROR, "insufficient memory to open file.\n" );
|
||||
if( !Avi->quiet )
|
||||
Con_DPrintf( S_ERROR "insufficient memory to open file.\n" );
|
||||
break;
|
||||
case AVIERR_FILEREAD:
|
||||
if( !Avi->quiet ) MsgDev( D_ERROR, "disk error reading file.\n" );
|
||||
if( !Avi->quiet )
|
||||
Con_DPrintf( S_ERROR "disk error reading file.\n" );
|
||||
break;
|
||||
case AVIERR_FILEOPEN:
|
||||
if( !Avi->quiet ) MsgDev( D_ERROR, "disk error opening file.\n" );
|
||||
if( !Avi->quiet )
|
||||
Con_DPrintf( S_ERROR "disk error opening file.\n" );
|
||||
break;
|
||||
case REGDB_E_CLASSNOTREG:
|
||||
default:
|
||||
if( !Avi->quiet ) MsgDev( D_ERROR, "no handler found (or file not found).\n" );
|
||||
if( !Avi->quiet )
|
||||
Con_DPrintf( S_ERROR "no handler found (or file not found).\n" );
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
@ -533,7 +565,7 @@ void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audi
|
|||
// read the audio header
|
||||
pAVIStreamReadFormat( Avi->audio_stream, pAVIStreamStart( Avi->audio_stream ), 0, &size );
|
||||
|
||||
Avi->audio_header = (WAVEFORMAT *)Mem_Alloc( cls.mempool, size );
|
||||
Avi->audio_header = (WAVEFORMAT *)Mem_Malloc( cls.mempool, size );
|
||||
pAVIStreamReadFormat( Avi->audio_stream, pAVIStreamStart( Avi->audio_stream ), Avi->audio_header, &size );
|
||||
Avi->audio_header_size = size;
|
||||
Avi->audio_codec = Avi->audio_header->wFormatTag;
|
||||
|
@ -565,7 +597,8 @@ void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audi
|
|||
{
|
||||
if( Avi->pfile ) // if file is open, close it
|
||||
pAVIFileRelease( Avi->pfile );
|
||||
if( !Avi->quiet ) MsgDev( D_ERROR, "couldn't find a valid video stream.\n" );
|
||||
if( !Avi->quiet )
|
||||
Con_DPrintf( S_ERROR "couldn't find a valid video stream.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -574,7 +607,8 @@ void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audi
|
|||
|
||||
if( Avi->video_getframe == NULL )
|
||||
{
|
||||
if( !Avi->quiet ) MsgDev( D_ERROR, "error attempting to read video frames.\n" );
|
||||
if( !Avi->quiet )
|
||||
Con_DPrintf( S_ERROR "error attempting to read video frames.\n" );
|
||||
return; // couldn't open frame getter.
|
||||
}
|
||||
|
||||
|
@ -619,10 +653,7 @@ movie_state_t *AVI_LoadVideo( const char *filename, qboolean load_audio )
|
|||
|
||||
// fast reject
|
||||
if( !avi_initialized )
|
||||
{
|
||||
MsgDev( D_ERROR, "AVI_LoadVideo: movie support is disabled\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// open cinematic
|
||||
Q_snprintf( path, sizeof( path ), "media/%s", filename );
|
||||
|
@ -631,11 +662,11 @@ movie_state_t *AVI_LoadVideo( const char *filename, qboolean load_audio )
|
|||
|
||||
if( FS_FileExists( path, false ) && !fullpath )
|
||||
{
|
||||
MsgDev( D_ERROR, "AVI_LoadVideo: Couldn't load %s from packfile. Please extract it\n", path );
|
||||
Con_Printf( "Couldn't load %s from packfile. Please extract it\n", path );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Avi = Mem_Alloc( cls.mempool, sizeof( movie_state_t ));
|
||||
Avi = Mem_Malloc( cls.mempool, sizeof( movie_state_t ));
|
||||
AVI_OpenVideo( Avi, fullpath, load_audio, false );
|
||||
|
||||
if( !AVI_IsActive( Avi ))
|
||||
|
@ -648,11 +679,6 @@ movie_state_t *AVI_LoadVideo( const char *filename, qboolean load_audio )
|
|||
return Avi;
|
||||
}
|
||||
|
||||
movie_state_t *AVI_LoadVideoNoSound( const char *filename )
|
||||
{
|
||||
return AVI_LoadVideo( filename, false );
|
||||
}
|
||||
|
||||
void AVI_FreeVideo( movie_state_t *state )
|
||||
{
|
||||
if( !state ) return;
|
||||
|
@ -668,34 +694,28 @@ qboolean AVI_Initailize( void )
|
|||
{
|
||||
if( Sys_CheckParm( "-noavi" ))
|
||||
{
|
||||
MsgDev( D_INFO, "AVI: Disabled\n" );
|
||||
Con_Printf( "AVI: Disabled\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !Sys_LoadLibrary( &avifile_dll ))
|
||||
{
|
||||
MsgDev( D_ERROR, "AVI_Initailize: failed\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !Sys_LoadLibrary( &msvfw_dll ))
|
||||
{
|
||||
MsgDev( D_ERROR, "AVI_Initailize: failed\n" );
|
||||
Sys_FreeLibrary( &avifile_dll );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !Sys_LoadLibrary( &msacm_dll ))
|
||||
{
|
||||
MsgDev( D_ERROR, "AVI_Initailize: failed\n" );
|
||||
Sys_FreeLibrary( &avifile_dll );
|
||||
Sys_FreeLibrary( &msvfw_dll );
|
||||
return false;
|
||||
}
|
||||
|
||||
pAVIFileInit();
|
||||
avi_initialized = true;
|
||||
MsgDev( D_NOTE, "AVI_Initailize: done\n" );
|
||||
pAVIFileInit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@ qboolean CL_ScreenshotGetName( int lastnum, char *filename )
|
|||
|
||||
if( lastnum < 0 || lastnum > 9999 )
|
||||
{
|
||||
MsgDev( D_ERROR, "unable to write screenshot\n" );
|
||||
Con_Printf( S_ERROR "unable to write screenshot\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ qboolean CL_SnapshotGetName( int lastnum, char *filename )
|
|||
|
||||
if( lastnum < 0 || lastnum > 9999 )
|
||||
{
|
||||
MsgDev( D_ERROR, "unable to write snapshot\n" );
|
||||
Con_Printf( S_ERROR "unable to write snapshot\n" );
|
||||
FS_AllowDirectPaths( false );
|
||||
return false;
|
||||
}
|
||||
|
@ -345,7 +345,7 @@ void CL_LevelShot_f( void )
|
|||
if( cls.demoplayback && ( cls.demonum != -1 ))
|
||||
{
|
||||
Q_sprintf( cls.shotname, "levelshots/%s_%s.bmp", cls.demoname, glState.wideScreen ? "16x9" : "4x3" );
|
||||
Q_snprintf( filename, sizeof( filename ), "demos/%s.dem", cls.demoname );
|
||||
Q_snprintf( filename, sizeof( filename ), "%s.dem", cls.demoname );
|
||||
|
||||
// make sure what levelshot is newer than demo
|
||||
ft1 = FS_FileTime( filename, false );
|
||||
|
@ -385,25 +385,6 @@ void CL_SaveShot_f( void )
|
|||
cls.scrshot_action = scrshot_savegame; // build new frame for saveshot
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_DemoShot_f
|
||||
|
||||
mini-pic in playdemo menu
|
||||
==================
|
||||
*/
|
||||
void CL_DemoShot_f( void )
|
||||
{
|
||||
if( Cmd_Argc() < 2 )
|
||||
{
|
||||
Con_Printf( S_USAGE "demoshot <demoname>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
Q_sprintf( cls.shotname, "demos/%s.bmp", Cmd_Argv( 1 ));
|
||||
cls.scrshot_action = scrshot_demoshot; // build new frame for demoshot
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
CL_DeleteDemo_f
|
||||
|
@ -424,9 +405,8 @@ void CL_DeleteDemo_f( void )
|
|||
return;
|
||||
}
|
||||
|
||||
// delete save and saveshot
|
||||
FS_Delete( va( "demos/%s.dem", Cmd_Argv( 1 )));
|
||||
FS_Delete( va( "demos/%s.bmp", Cmd_Argv( 1 )));
|
||||
// delete demo
|
||||
FS_Delete( va( "%s.dem", Cmd_Argv( 1 )));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -44,19 +44,19 @@ qboolean CL_CheckFile( sizebuf_t *msg, resource_t *pResource )
|
|||
|
||||
if( !COM_IsSafeFileToDownload( filepath ))
|
||||
{
|
||||
MsgDev( D_REPORT, "refusing to download %s\n", filepath );
|
||||
Con_Reportf( "refusing to download %s\n", filepath );
|
||||
return true;
|
||||
}
|
||||
|
||||
if( !cl_allow_download.value )
|
||||
{
|
||||
MsgDev( D_REPORT, "Download refused, cl_allow_download is 0\n" );
|
||||
Con_Reportf( "Download refused, cl_allow_download is 0\n" );
|
||||
return true;
|
||||
}
|
||||
|
||||
if( cls.state == ca_active && !cl_download_ingame.value )
|
||||
{
|
||||
MsgDev( D_REPORT, "In-game download refused...\n" );
|
||||
Con_Reportf( "In-game download refused...\n" );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ qboolean CL_CheckFile( sizebuf_t *msg, resource_t *pResource )
|
|||
|
||||
if( cls.demoplayback )
|
||||
{
|
||||
MsgDev( D_WARN, "file %s missing during demo playback.\n", filepath );
|
||||
Con_Reportf( S_WARN "file %s missing during demo playback.\n", filepath );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ void CL_AddToResourceList( resource_t *pResource, resource_t *pList )
|
|||
{
|
||||
if( pResource->pPrev != NULL || pResource->pNext != NULL )
|
||||
{
|
||||
MsgDev( D_ERROR, "Resource already linked\n" );
|
||||
Con_Reportf( S_ERROR "Resource already linked\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ void CL_MoveToOnHandList( resource_t *pResource )
|
|||
{
|
||||
if( !pResource )
|
||||
{
|
||||
MsgDev( D_REPORT, "Null resource passed to CL_MoveToOnHandList\n" );
|
||||
Con_Reportf( "Null resource passed to CL_MoveToOnHandList\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
242
engine/client/cl_debug.c
Normal file
242
engine/client/cl_debug.c
Normal file
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
cl_debug.c - server message debugging
|
||||
Copyright (C) 2018 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 "net_encode.h"
|
||||
#include "particledef.h"
|
||||
#include "gl_local.h"
|
||||
#include "cl_tent.h"
|
||||
#include "shake.h"
|
||||
#include "hltv.h"
|
||||
#include "input.h"
|
||||
|
||||
#define MSG_COUNT 32 // last 32 messages parsed
|
||||
#define MSG_MASK (MSG_COUNT - 1)
|
||||
|
||||
const char *svc_strings[svc_lastmsg+1] =
|
||||
{
|
||||
"svc_bad",
|
||||
"svc_nop",
|
||||
"svc_disconnect",
|
||||
"svc_event",
|
||||
"svc_changing",
|
||||
"svc_setview",
|
||||
"svc_sound",
|
||||
"svc_time",
|
||||
"svc_print",
|
||||
"svc_stufftext",
|
||||
"svc_setangle",
|
||||
"svc_serverdata",
|
||||
"svc_lightstyle",
|
||||
"svc_updateuserinfo",
|
||||
"svc_deltatable",
|
||||
"svc_clientdata",
|
||||
"svc_resource",
|
||||
"svc_pings",
|
||||
"svc_particle",
|
||||
"svc_restoresound",
|
||||
"svc_spawnstatic",
|
||||
"svc_event_reliable",
|
||||
"svc_spawnbaseline",
|
||||
"svc_temp_entity",
|
||||
"svc_setpause",
|
||||
"svc_signonnum",
|
||||
"svc_centerprint",
|
||||
"svc_unused27",
|
||||
"svc_unused28",
|
||||
"svc_unused29",
|
||||
"svc_intermission",
|
||||
"svc_finale",
|
||||
"svc_cdtrack",
|
||||
"svc_restore",
|
||||
"svc_cutscene",
|
||||
"svc_weaponanim",
|
||||
"svc_bspdecal",
|
||||
"svc_roomtype",
|
||||
"svc_addangle",
|
||||
"svc_usermessage",
|
||||
"svc_packetentities",
|
||||
"svc_deltapacketentities",
|
||||
"svc_choke",
|
||||
"svc_resourcelist",
|
||||
"svc_deltamovevars",
|
||||
"svc_resourcerequest",
|
||||
"svc_customization",
|
||||
"svc_crosshairangle",
|
||||
"svc_soundfade",
|
||||
"svc_filetxferfailed",
|
||||
"svc_hltv",
|
||||
"svc_director",
|
||||
"svc_voiceinit",
|
||||
"svc_voicedata",
|
||||
"svc_deltapacketbones",
|
||||
"svc_unused55",
|
||||
"svc_resourcelocation",
|
||||
"svc_querycvarvalue",
|
||||
"svc_querycvarvalue2",
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int command;
|
||||
int starting_offset;
|
||||
int frame_number;
|
||||
} oldcmd_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
oldcmd_t oldcmd[MSG_COUNT];
|
||||
int currentcmd;
|
||||
qboolean parsing;
|
||||
} msg_debug_t;
|
||||
|
||||
static msg_debug_t cls_message_debug;
|
||||
|
||||
const char *CL_MsgInfo( int cmd )
|
||||
{
|
||||
static string sz;
|
||||
|
||||
Q_strcpy( sz, "???" );
|
||||
|
||||
if( cmd >= 0 && cmd <= svc_lastmsg )
|
||||
{
|
||||
// get engine message name
|
||||
Q_strncpy( sz, svc_strings[cmd], sizeof( sz ));
|
||||
}
|
||||
else if( cmd > svc_lastmsg && cmd <= ( svc_lastmsg + MAX_USER_MESSAGES ))
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < MAX_USER_MESSAGES; i++ )
|
||||
{
|
||||
if( clgame.msg[i].number == cmd )
|
||||
{
|
||||
Q_strncpy( sz, clgame.msg[i].name, sizeof( sz ));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_Parse_Debug
|
||||
|
||||
enable message debugging
|
||||
=====================
|
||||
*/
|
||||
void CL_Parse_Debug( qboolean enable )
|
||||
{
|
||||
cls_message_debug.parsing = enable;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_Parse_RecordCommand
|
||||
|
||||
record new message params into debug buffer
|
||||
=====================
|
||||
*/
|
||||
void CL_Parse_RecordCommand( int cmd, int startoffset )
|
||||
{
|
||||
int slot;
|
||||
|
||||
if( cmd == svc_nop ) return;
|
||||
|
||||
slot = ( cls_message_debug.currentcmd++ & MSG_MASK );
|
||||
cls_message_debug.oldcmd[slot].command = cmd;
|
||||
cls_message_debug.oldcmd[slot].starting_offset = startoffset;
|
||||
cls_message_debug.oldcmd[slot].frame_number = host.framecount;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_ResetFrame
|
||||
=====================
|
||||
*/
|
||||
void CL_ResetFrame( frame_t *frame )
|
||||
{
|
||||
memset( &frame->graphdata, 0, sizeof( netbandwidthgraph_t ));
|
||||
frame->receivedtime = host.realtime;
|
||||
frame->valid = true;
|
||||
frame->choked = false;
|
||||
frame->latency = 0.0;
|
||||
frame->time = cl.mtime[0];
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_WriteErrorMessage
|
||||
|
||||
write net_message into buffer.dat for debugging
|
||||
=====================
|
||||
*/
|
||||
static void CL_WriteErrorMessage( int current_count, sizebuf_t *msg )
|
||||
{
|
||||
const char *buffer_file = "buffer.dat";
|
||||
file_t *fp;
|
||||
|
||||
fp = FS_Open( buffer_file, "wb", false );
|
||||
if( !fp ) return;
|
||||
|
||||
FS_Write( fp, &cls.starting_count, sizeof( int ));
|
||||
FS_Write( fp, ¤t_count, sizeof( int ));
|
||||
FS_Write( fp, MSG_GetData( msg ), MSG_GetMaxBytes( msg ));
|
||||
FS_Close( fp );
|
||||
|
||||
Con_Printf( "Wrote erroneous message to %s\n", buffer_file );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_WriteMessageHistory
|
||||
|
||||
list last 32 messages for debugging net troubleshooting
|
||||
=====================
|
||||
*/
|
||||
void CL_WriteMessageHistory( void )
|
||||
{
|
||||
oldcmd_t *old, *failcommand;
|
||||
sizebuf_t *msg = &net_message;
|
||||
int i, thecmd;
|
||||
|
||||
if( !cls.initialized || cls.state == ca_disconnected )
|
||||
return;
|
||||
|
||||
if( !cls_message_debug.parsing )
|
||||
return;
|
||||
|
||||
Con_Printf( "Last %i messages parsed.\n", MSG_COUNT );
|
||||
|
||||
// finish here
|
||||
thecmd = cls_message_debug.currentcmd - 1;
|
||||
thecmd -= ( MSG_COUNT - 1 ); // back up to here
|
||||
|
||||
for( i = 0; i < MSG_COUNT - 1; i++ )
|
||||
{
|
||||
thecmd &= MSG_MASK;
|
||||
old = &cls_message_debug.oldcmd[thecmd];
|
||||
Con_Printf( "%i %04i %s\n", old->frame_number, old->starting_offset, CL_MsgInfo( old->command ));
|
||||
thecmd++;
|
||||
}
|
||||
|
||||
failcommand = &cls_message_debug.oldcmd[thecmd];
|
||||
Con_Printf( "BAD: %3i:%s\n", MSG_GetNumBytesRead( msg ) - 1, CL_MsgInfo( failcommand->command ));
|
||||
if( host_developer.value >= DEV_EXTENDED )
|
||||
CL_WriteErrorMessage( MSG_GetNumBytesRead( msg ) - 1, msg );
|
||||
cls_message_debug.parsing = false;
|
||||
}
|
|
@ -126,7 +126,7 @@ void CL_StartupDemoHeader( void )
|
|||
|
||||
if( !cls.demoheader )
|
||||
{
|
||||
MsgDev( D_ERROR, "couldn't open temporary header file.\n" );
|
||||
Con_DPrintf( S_ERROR "couldn't open temporary header file.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -349,9 +349,9 @@ Write demo header
|
|||
*/
|
||||
void CL_WriteDemoHeader( const char *name )
|
||||
{
|
||||
long copysize;
|
||||
long savepos;
|
||||
long curpos;
|
||||
int copysize;
|
||||
int savepos;
|
||||
int curpos;
|
||||
|
||||
Con_Printf( "recording to %s.\n", name );
|
||||
cls.demofile = FS_Open( name, "wb", false );
|
||||
|
@ -359,7 +359,7 @@ void CL_WriteDemoHeader( const char *name )
|
|||
|
||||
if( !cls.demofile )
|
||||
{
|
||||
MsgDev( D_ERROR, "couldn't open %s.\n", name );
|
||||
Con_Printf( S_ERROR "couldn't open %s.\n", name );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -380,7 +380,7 @@ void CL_WriteDemoHeader( const char *name )
|
|||
FS_Write( cls.demofile, &demo.header, sizeof( demo.header ));
|
||||
|
||||
demo.directory.numentries = 2;
|
||||
demo.directory.entries = Mem_Alloc( cls.mempool, sizeof( demoentry_t ) * demo.directory.numentries );
|
||||
demo.directory.entries = Mem_Calloc( cls.mempool, sizeof( demoentry_t ) * demo.directory.numentries );
|
||||
|
||||
// DIRECTORY ENTRY # 0
|
||||
demo.entry = &demo.directory.entries[0]; // only one here.
|
||||
|
@ -489,7 +489,7 @@ void CL_DrawDemoRecording( void )
|
|||
{
|
||||
char string[64];
|
||||
rgba_t color = { 255, 255, 255, 255 };
|
||||
long pos;
|
||||
int pos;
|
||||
int len;
|
||||
|
||||
if(!( host_developer.value && cls.demorecording ))
|
||||
|
@ -500,7 +500,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 >> 2, string, color );
|
||||
Con_DrawString(( glState.width - len ) >> 1, glState.height >> 4, string, color );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -626,6 +626,49 @@ void CL_ReadDemoSequence( qboolean discard )
|
|||
cls.netchan.last_reliable_sequence = last_reliable_sequence;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_DemoStartPlayback
|
||||
=================
|
||||
*/
|
||||
void CL_DemoStartPlayback( int mode )
|
||||
{
|
||||
if( cls.changedemo )
|
||||
{
|
||||
S_StopAllSounds( true );
|
||||
SCR_BeginLoadingPlaque( false );
|
||||
|
||||
CL_ClearState ();
|
||||
CL_InitEdicts (); // re-arrange edicts
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: at this point demo is still valid
|
||||
CL_Disconnect();
|
||||
Host_ShutdownServer();
|
||||
|
||||
Con_FastClose();
|
||||
UI_SetActiveMenu( false );
|
||||
}
|
||||
|
||||
cls.demoplayback = mode;
|
||||
cls.state = ca_connected;
|
||||
cl.background = (cls.demonum != -1) ? true : false;
|
||||
cls.spectator = false;
|
||||
cls.signon = 0;
|
||||
|
||||
demo.starttime = CL_GetDemoPlaybackClock(); // for determining whether to read another message
|
||||
|
||||
Netchan_Setup( NS_CLIENT, &cls.netchan, net_from, Cvar_VariableInteger( "net_qport" ), NULL, CL_GetFragmentSize );
|
||||
|
||||
memset( demo.cmds, 0, sizeof( demo.cmds ));
|
||||
demo.angle_position = 1;
|
||||
demo.framecount = 0;
|
||||
cls.lastoutgoingcommand = -1;
|
||||
cls.nextcmdtime = host.realtime;
|
||||
cl.last_command_ack = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_DemoAborted
|
||||
|
@ -657,7 +700,7 @@ void CL_DemoCompleted( void )
|
|||
|
||||
CL_StopPlayback();
|
||||
|
||||
if( !CL_NextDemo() && host_developer.value <= DEV_NONE )
|
||||
if( !CL_NextDemo() && !cls.changedemo )
|
||||
UI_SetActiveMenu( true );
|
||||
|
||||
Cvar_SetValue( "v_dark", 0.0f );
|
||||
|
@ -705,14 +748,14 @@ qboolean CL_ReadRawNetworkData( byte *buffer, size_t *length )
|
|||
|
||||
if( msglen < 0 )
|
||||
{
|
||||
MsgDev( D_ERROR, "Demo message length < 0\n" );
|
||||
Con_Reportf( S_ERROR "Demo message length < 0\n" );
|
||||
CL_DemoCompleted();
|
||||
return false;
|
||||
}
|
||||
|
||||
if( msglen > MAX_INIT_MSG )
|
||||
{
|
||||
MsgDev( D_ERROR, "Demo message %i > %i\n", msglen, MAX_INIT_MSG );
|
||||
Con_Reportf( S_ERROR "Demo message %i > %i\n", msglen, MAX_INIT_MSG );
|
||||
CL_DemoCompleted();
|
||||
return false;
|
||||
}
|
||||
|
@ -721,12 +764,14 @@ qboolean CL_ReadRawNetworkData( byte *buffer, size_t *length )
|
|||
{
|
||||
if( FS_Read( cls.demofile, buffer, msglen ) != msglen )
|
||||
{
|
||||
MsgDev( D_ERROR, "Error reading demo message data\n" );
|
||||
Con_Reportf( S_ERROR "Error reading demo message data\n" );
|
||||
CL_DemoCompleted();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
cls.netchan.last_received = host.realtime;
|
||||
cls.netchan.total_received += msglen;
|
||||
*length = msglen;
|
||||
|
||||
if( cls.state != ca_active )
|
||||
|
@ -735,6 +780,99 @@ qboolean CL_ReadRawNetworkData( byte *buffer, size_t *length )
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_DemoReadMessageQuake
|
||||
|
||||
reads demo data and write it to client
|
||||
=================
|
||||
*/
|
||||
qboolean CL_DemoReadMessageQuake( byte *buffer, size_t *length )
|
||||
{
|
||||
vec3_t viewangles;
|
||||
int msglen = 0;
|
||||
demoangle_t *a;
|
||||
|
||||
*length = 0; // assume we fail
|
||||
|
||||
// decide if it is time to grab the next message
|
||||
if( cls.signon == SIGNONS ) // allways grab until fully connected
|
||||
{
|
||||
if( cls.timedemo )
|
||||
{
|
||||
if( host.framecount == cls.td_lastframe )
|
||||
return false; // already read this frame's message
|
||||
|
||||
cls.td_lastframe = host.framecount;
|
||||
|
||||
// if this is the second frame, grab the real td_starttime
|
||||
// so the bogus time on the first frame doesn't count
|
||||
if( host.framecount == cls.td_startframe + 1 )
|
||||
cls.td_starttime = host.realtime;
|
||||
}
|
||||
else if( cl.time <= cl.mtime[0] )
|
||||
{
|
||||
// don't need another message yet
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// get the next message
|
||||
FS_Read( cls.demofile, &msglen, sizeof( int ));
|
||||
FS_Read( cls.demofile, &viewangles[0], sizeof( float ));
|
||||
FS_Read( cls.demofile, &viewangles[1], sizeof( float ));
|
||||
FS_Read( cls.demofile, &viewangles[2], sizeof( float ));
|
||||
cls.netchan.incoming_sequence++;
|
||||
demo.timestamp = cl.mtime[0];
|
||||
cl.skip_interp = false;
|
||||
|
||||
// make sure what interp info contain angles from different frames
|
||||
// or lerping will stop working
|
||||
if( demo.lasttime != demo.timestamp )
|
||||
{
|
||||
// select entry into circular buffer
|
||||
demo.angle_position = (demo.angle_position + 1) & ANGLE_MASK;
|
||||
a = &demo.cmds[demo.angle_position];
|
||||
|
||||
// record update
|
||||
a->starttime = demo.timestamp;
|
||||
VectorCopy( viewangles, a->viewangles );
|
||||
demo.lasttime = demo.timestamp;
|
||||
}
|
||||
|
||||
if( msglen < 0 )
|
||||
{
|
||||
Con_Reportf( S_ERROR "Demo message length < 0\n" );
|
||||
CL_DemoCompleted();
|
||||
return false;
|
||||
}
|
||||
|
||||
if( msglen > MAX_INIT_MSG )
|
||||
{
|
||||
Con_Reportf( S_ERROR "Demo message %i > %i\n", msglen, MAX_INIT_MSG );
|
||||
CL_DemoCompleted();
|
||||
return false;
|
||||
}
|
||||
|
||||
if( msglen > 0 )
|
||||
{
|
||||
if( FS_Read( cls.demofile, buffer, msglen ) != msglen )
|
||||
{
|
||||
Con_Reportf( S_ERROR "Error reading demo message data\n" );
|
||||
CL_DemoCompleted();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
cls.netchan.last_received = host.realtime;
|
||||
cls.netchan.total_received += msglen;
|
||||
*length = msglen;
|
||||
|
||||
if( cls.state != ca_active )
|
||||
Cbuf_Execute();
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_DemoReadMessage
|
||||
|
@ -754,7 +892,6 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length )
|
|||
|
||||
if( !cls.demofile )
|
||||
{
|
||||
MsgDev( D_ERROR, "tried to read a demo message with no demo file\n" );
|
||||
CL_DemoCompleted();
|
||||
return false;
|
||||
}
|
||||
|
@ -765,6 +902,9 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length )
|
|||
return false; // paused
|
||||
}
|
||||
|
||||
if( cls.demoplayback == DEMO_QUAKE1 )
|
||||
return CL_DemoReadMessageQuake( buffer, length );
|
||||
|
||||
do
|
||||
{
|
||||
qboolean bSkipMessage = false;
|
||||
|
@ -812,7 +952,7 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length )
|
|||
return false; // header is ended, skip frame
|
||||
case dem_userdata:
|
||||
FS_Read( cls.demofile, &size, sizeof( int ));
|
||||
userbuf = Mem_Alloc( cls.mempool, size );
|
||||
userbuf = Mem_Malloc( cls.mempool, size );
|
||||
FS_Read( cls.demofile, userbuf, size );
|
||||
|
||||
if( clgame.hInstance )
|
||||
|
@ -915,14 +1055,26 @@ but viewangles interpolate here
|
|||
*/
|
||||
void CL_DemoInterpolateAngles( void )
|
||||
{
|
||||
float curtime = (CL_GetDemoPlaybackClock() - demo.starttime) - host.frametime;
|
||||
demoangle_t *prev = NULL, *next = NULL;
|
||||
float frac = 0.0f;
|
||||
float curtime;
|
||||
|
||||
if( cls.demoplayback == DEMO_QUAKE1 )
|
||||
{
|
||||
// manually select next & prev states
|
||||
next = &demo.cmds[(demo.angle_position - 0) & ANGLE_MASK];
|
||||
prev = &demo.cmds[(demo.angle_position - 1) & ANGLE_MASK];
|
||||
if( cl.skip_interp ) *prev = *next; // camera was teleported
|
||||
frac = cl.lerpFrac;
|
||||
}
|
||||
else
|
||||
{
|
||||
curtime = (CL_GetDemoPlaybackClock() - demo.starttime) - host.frametime;
|
||||
if( curtime > demo.timestamp )
|
||||
curtime = demo.timestamp; // don't run too far
|
||||
|
||||
CL_DemoFindInterpolatedViewAngles( curtime, &frac, &prev, &next );
|
||||
}
|
||||
|
||||
if( prev && next )
|
||||
{
|
||||
|
@ -933,7 +1085,8 @@ void CL_DemoInterpolateAngles( void )
|
|||
QuaternionSlerp( q2, q1, frac, q );
|
||||
QuaternionAngle( q, cl.viewangles );
|
||||
}
|
||||
else VectorCopy( cl.cmd->viewangles, cl.viewangles );
|
||||
else if( cl.cmd != NULL )
|
||||
VectorCopy( cl.cmd->viewangles, cl.viewangles );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -976,6 +1129,7 @@ void CL_StopPlayback( void )
|
|||
cls.demofile = NULL;
|
||||
|
||||
cls.olddemonum = Q_max( -1, cls.demonum - 1 );
|
||||
if( demo.directory.entries != NULL )
|
||||
Mem_Free( demo.directory.entries );
|
||||
cls.td_lastframe = host.framecount;
|
||||
demo.directory.numentries = 0;
|
||||
|
@ -999,6 +1153,7 @@ void CL_StopPlayback( void )
|
|||
// let game known about demo state
|
||||
Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
|
||||
cls.state = ca_disconnected;
|
||||
cls.set_lastdemo = false;
|
||||
S_StopBackgroundTrack();
|
||||
cls.connect_time = 0;
|
||||
cls.demonum = -1;
|
||||
|
@ -1110,16 +1265,45 @@ qboolean CL_NextDemo( void )
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_CheckStartupDemos
|
||||
|
||||
queue demos loop after movie playing
|
||||
==================
|
||||
*/
|
||||
void CL_CheckStartupDemos( void )
|
||||
{
|
||||
if( !cls.demos_pending )
|
||||
return; // no demos in loop
|
||||
|
||||
if( cls.movienum != -1 )
|
||||
return; // wait until movies finished
|
||||
|
||||
if( GameState->nextstate != STATE_RUNFRAME || cls.demoplayback )
|
||||
{
|
||||
// commandline override
|
||||
cls.demos_pending = false;
|
||||
cls.demonum = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
// run demos loop in background mode
|
||||
Cvar_SetValue( "v_dark", 1.0f );
|
||||
cls.demos_pending = false;
|
||||
cls.demonum = 0;
|
||||
CL_NextDemo ();
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_DemoGetName
|
||||
==================
|
||||
*/
|
||||
void CL_DemoGetName( int lastnum, char *filename )
|
||||
static void CL_DemoGetName( int lastnum, char *filename )
|
||||
{
|
||||
int a, b, c, d;
|
||||
|
||||
if( !filename ) return;
|
||||
if( lastnum < 0 || lastnum > 9999 )
|
||||
{
|
||||
// bound
|
||||
|
@ -1148,8 +1332,8 @@ Begins recording a demo from the current position
|
|||
*/
|
||||
void CL_Record_f( void )
|
||||
{
|
||||
string demoname, demopath;
|
||||
const char *name;
|
||||
string demoname, demopath, demoshot;
|
||||
int n;
|
||||
|
||||
if( Cmd_Argc() == 1 )
|
||||
|
@ -1190,7 +1374,7 @@ void CL_Record_f( void )
|
|||
for( n = 0; n < 10000; n++ )
|
||||
{
|
||||
CL_DemoGetName( n, demoname );
|
||||
if( !FS_FileExists( va( "demos/%s.dem", demoname ), true ))
|
||||
if( !FS_FileExists( va( "%s.dem", demoname ), true ))
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1203,18 +1387,12 @@ void CL_Record_f( void )
|
|||
else Q_strncpy( demoname, name, sizeof( demoname ));
|
||||
|
||||
// open the demo file
|
||||
Q_sprintf( demopath, "demos/%s.dem", demoname );
|
||||
Q_sprintf( demoshot, "demos/%s.bmp", demoname );
|
||||
|
||||
// unload previous image from memory (it's will be overwritten)
|
||||
GL_FreeImage( demoshot );
|
||||
Q_sprintf( demopath, "%s.dem", demoname );
|
||||
|
||||
// make sure what old demo is removed
|
||||
if( FS_FileExists( demopath, false )) FS_Delete( demopath );
|
||||
if( FS_FileExists( demoshot, false )) FS_Delete( demoshot );
|
||||
if( FS_FileExists( demopath, false ))
|
||||
FS_Delete( demopath );
|
||||
|
||||
// write demoshot for preview
|
||||
Cbuf_AddText( va( "demoshot \"%s\"\n", demoname ));
|
||||
Q_strncpy( cls.demoname, demoname, sizeof( cls.demoname ));
|
||||
Q_strncpy( gameui.globals->demoname, demoname, sizeof( gameui.globals->demoname ));
|
||||
|
||||
|
@ -1230,11 +1408,11 @@ playdemo <demoname>
|
|||
*/
|
||||
void CL_PlayDemo_f( void )
|
||||
{
|
||||
string filename;
|
||||
string demoname;
|
||||
int i;
|
||||
char filename[MAX_QPATH];
|
||||
char demoname[MAX_QPATH];
|
||||
int i, ident;
|
||||
|
||||
if( Cmd_Argc() != 2 )
|
||||
if( Cmd_Argc() < 2 )
|
||||
{
|
||||
Con_Printf( S_USAGE "playdemo <demoname>\n" );
|
||||
return;
|
||||
|
@ -1251,12 +1429,21 @@ void CL_PlayDemo_f( void )
|
|||
return;
|
||||
}
|
||||
|
||||
Q_strncpy( demoname, Cmd_Argv( 1 ), sizeof( demoname ) - 1 );
|
||||
Q_snprintf( filename, sizeof( filename ), "demos/%s.dem", demoname );
|
||||
Q_strncpy( demoname, Cmd_Argv( 1 ), sizeof( demoname ));
|
||||
COM_StripExtension( demoname );
|
||||
Q_snprintf( filename, sizeof( filename ), "%s.dem", demoname );
|
||||
|
||||
// hidden parameter
|
||||
if( Cmd_Argc() > 2 )
|
||||
cls.set_lastdemo = Q_atoi( Cmd_Argv( 2 ));
|
||||
|
||||
// member last demo
|
||||
if( cls.set_lastdemo )
|
||||
Cvar_Set( "lastdemo", demoname );
|
||||
|
||||
if( !FS_FileExists( filename, true ))
|
||||
{
|
||||
MsgDev( D_ERROR, "couldn't open %s\n", filename );
|
||||
Con_Printf( S_ERROR "couldn't open %s\n", filename );
|
||||
CL_DemoAborted();
|
||||
return;
|
||||
}
|
||||
|
@ -1265,12 +1452,34 @@ void CL_PlayDemo_f( void )
|
|||
Q_strncpy( cls.demoname, demoname, sizeof( cls.demoname ));
|
||||
Q_strncpy( gameui.globals->demoname, demoname, sizeof( gameui.globals->demoname ));
|
||||
|
||||
// read in the m_DemoHeader
|
||||
FS_Read( cls.demofile, &ident, sizeof( int ));
|
||||
FS_Seek( cls.demofile, 0, SEEK_SET ); // rewind back to start
|
||||
cls.forcetrack = 0;
|
||||
|
||||
// check for quake demos
|
||||
if( ident != IDEMOHEADER )
|
||||
{
|
||||
int c, neg = false;
|
||||
|
||||
demo.header.host_fps = host_maxfps->value;
|
||||
|
||||
while(( c = FS_Getc( cls.demofile )) != '\n' )
|
||||
{
|
||||
if( c == '-' ) neg = true;
|
||||
else cls.forcetrack = cls.forcetrack * 10 + (c - '0');
|
||||
}
|
||||
|
||||
if( neg ) cls.forcetrack = -cls.forcetrack;
|
||||
CL_DemoStartPlayback( DEMO_QUAKE1 );
|
||||
return; // quake demo is started
|
||||
}
|
||||
|
||||
// read in the demo header
|
||||
FS_Read( cls.demofile, &demo.header, sizeof( demoheader_t ));
|
||||
|
||||
if( demo.header.id != IDEMOHEADER )
|
||||
{
|
||||
MsgDev( D_ERROR, "%s is not a demo file\n", filename );
|
||||
Con_Printf( S_ERROR "%s is not a demo file\n", demoname );
|
||||
CL_DemoAborted();
|
||||
return;
|
||||
}
|
||||
|
@ -1278,10 +1487,10 @@ void CL_PlayDemo_f( void )
|
|||
if( demo.header.net_protocol != PROTOCOL_VERSION || demo.header.dem_protocol != DEMO_PROTOCOL )
|
||||
{
|
||||
if( demo.header.dem_protocol != DEMO_PROTOCOL )
|
||||
MsgDev( D_ERROR, "playdemo: demo protocol outdated (%i should be %i)\n", demo.header.dem_protocol, DEMO_PROTOCOL );
|
||||
Con_Printf( S_ERROR "playdemo: demo protocol outdated (%i should be %i)\n", demo.header.dem_protocol, DEMO_PROTOCOL );
|
||||
|
||||
if( demo.header.net_protocol != PROTOCOL_VERSION )
|
||||
MsgDev( D_ERROR, "playdemo: net protocol outdated (%i should be %i)\n", demo.header.net_protocol, PROTOCOL_VERSION );
|
||||
Con_Printf( S_ERROR "playdemo: net protocol outdated (%i should be %i)\n", demo.header.net_protocol, PROTOCOL_VERSION );
|
||||
CL_DemoAborted();
|
||||
return;
|
||||
}
|
||||
|
@ -1292,31 +1501,13 @@ void CL_PlayDemo_f( void )
|
|||
|
||||
if( demo.directory.numentries < 1 || demo.directory.numentries > 1024 )
|
||||
{
|
||||
MsgDev( D_ERROR, "demo had bogus # of directory entries: %i\n", demo.directory.numentries );
|
||||
Con_Printf( S_ERROR "demo had bogus # of directory entries: %i\n", demo.directory.numentries );
|
||||
CL_DemoAborted();
|
||||
return;
|
||||
}
|
||||
|
||||
if( cls.changedemo )
|
||||
{
|
||||
S_StopAllSounds( true );
|
||||
SCR_BeginLoadingPlaque( false );
|
||||
|
||||
CL_ClearState ();
|
||||
CL_InitEdicts (); // re-arrange edicts
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: at this point demo is still valid
|
||||
CL_Disconnect();
|
||||
Host_ShutdownServer();
|
||||
|
||||
Con_FastClose();
|
||||
UI_SetActiveMenu( false );
|
||||
}
|
||||
|
||||
// allocate demo entries
|
||||
demo.directory.entries = Mem_Alloc( cls.mempool, sizeof( demoentry_t ) * demo.directory.numentries );
|
||||
demo.directory.entries = Mem_Malloc( cls.mempool, sizeof( demoentry_t ) * demo.directory.numentries );
|
||||
|
||||
for( i = 0; i < demo.directory.numentries; i++ )
|
||||
{
|
||||
|
@ -1328,22 +1519,7 @@ void CL_PlayDemo_f( void )
|
|||
|
||||
FS_Seek( cls.demofile, demo.entry->offset, SEEK_SET );
|
||||
|
||||
cls.demoplayback = true;
|
||||
cls.state = ca_connected;
|
||||
cl.background = (cls.demonum != -1) ? true : false;
|
||||
cls.spectator = false;
|
||||
cls.signon = 0;
|
||||
|
||||
demo.starttime = CL_GetDemoPlaybackClock(); // for determining whether to read another message
|
||||
|
||||
Netchan_Setup( NS_CLIENT, &cls.netchan, net_from, Cvar_VariableInteger( "net_qport" ), NULL, CL_GetFragmentSize );
|
||||
|
||||
memset( demo.cmds, 0, sizeof( demo.cmds ));
|
||||
demo.angle_position = 1;
|
||||
demo.framecount = 0;
|
||||
cls.lastoutgoingcommand = -1;
|
||||
cls.nextcmdtime = host.realtime;
|
||||
cl.last_command_ack = -1;
|
||||
CL_DemoStartPlayback( DEMO_XASH3D );
|
||||
|
||||
// g-cont. is this need?
|
||||
Q_strncpy( cls.servername, demoname, sizeof( cls.servername ));
|
||||
|
@ -1394,7 +1570,7 @@ void CL_StartDemos_f( void )
|
|||
c = Cmd_Argc() - 1;
|
||||
if( c > MAX_DEMOS )
|
||||
{
|
||||
MsgDev( D_WARN, "Host_StartDemos: max %i demos in demoloop\n", MAX_DEMOS );
|
||||
Con_DPrintf( S_WARN "Host_StartDemos: max %i demos in demoloop\n", MAX_DEMOS );
|
||||
c = MAX_DEMOS;
|
||||
}
|
||||
|
||||
|
@ -1402,15 +1578,7 @@ void CL_StartDemos_f( void )
|
|||
|
||||
for( i = 1; i < c + 1; i++ )
|
||||
Q_strncpy( cls.demos[i-1], Cmd_Argv( i ), sizeof( cls.demos[0] ));
|
||||
|
||||
if( !SV_Active() && !cls.demoplayback )
|
||||
{
|
||||
// run demos loop in background mode
|
||||
Cvar_SetValue( "v_dark", 1.0f );
|
||||
cls.demonum = 0;
|
||||
CL_NextDemo ();
|
||||
}
|
||||
else cls.demonum = -1;
|
||||
cls.demos_pending = true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1428,17 +1596,15 @@ void CL_Demos_f( void )
|
|||
return;
|
||||
}
|
||||
|
||||
// demos loop are not running
|
||||
if( cls.olddemonum == -1 )
|
||||
return;
|
||||
|
||||
cls.demonum = cls.olddemonum;
|
||||
|
||||
if( cls.demonum == -1 )
|
||||
cls.demonum = 0;
|
||||
|
||||
if( !SV_Active() && !cls.demoplayback )
|
||||
{
|
||||
// run demos loop in background mode
|
||||
cls.changedemo = true;
|
||||
if( !SV_Active() && !cls.demoplayback )
|
||||
CL_NextDemo ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -157,14 +157,11 @@ void CL_RegisterEvent( int lastnum, const char *szEvName, pfnEventHook func )
|
|||
cl_user_event_t *ev;
|
||||
|
||||
if( lastnum == MAX_EVENTS )
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_RegisterEvent: MAX_EVENTS hit!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// clear existing or allocate new one
|
||||
if( !clgame.events[lastnum] )
|
||||
clgame.events[lastnum] = Mem_Alloc( cls.mempool, sizeof( cl_user_event_t ));
|
||||
clgame.events[lastnum] = Mem_Calloc( cls.mempool, sizeof( cl_user_event_t ));
|
||||
else memset( clgame.events[lastnum], 0, sizeof( cl_user_event_t ));
|
||||
|
||||
ev = clgame.events[lastnum];
|
||||
|
@ -197,7 +194,7 @@ qboolean CL_FireEvent( event_info_t *ei, int slot )
|
|||
if( !ev )
|
||||
{
|
||||
idx = bound( 1, ei->index, ( MAX_EVENTS - 1 ));
|
||||
MsgDev( D_ERROR, "CL_FireEvent: %s not precached\n", cl.event_precache[idx] );
|
||||
Con_Reportf( S_ERROR "CL_FireEvent: %s not precached\n", cl.event_precache[idx] );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -211,7 +208,7 @@ qboolean CL_FireEvent( event_info_t *ei, int slot )
|
|||
}
|
||||
|
||||
name = cl.event_precache[ei->index];
|
||||
MsgDev( D_ERROR, "CL_FireEvent: %s not hooked\n", name );
|
||||
Con_Reportf( S_ERROR "CL_FireEvent: %s not hooked\n", name );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -396,7 +393,7 @@ void CL_ParseEvent( sizebuf_t *msg )
|
|||
event_index = MSG_ReadUBitLong( msg, MAX_EVENT_BITS );
|
||||
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
packet_index = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
|
||||
packet_index = MSG_ReadUBitLong( msg, cls.legacymode ? MAX_LEGACY_ENTITY_BITS : MAX_ENTITY_BITS );
|
||||
else packet_index = -1;
|
||||
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
|
@ -439,10 +436,6 @@ void CL_ParseEvent( sizebuf_t *msg )
|
|||
if( args.entindex > 0 && args.entindex <= cl.maxclients )
|
||||
args.angles[PITCH] /= -3.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
MsgDev( D_WARN, "CL_ParseEvent: Received non-packet entity index 0 for event\n" );
|
||||
}
|
||||
}
|
||||
|
||||
// Place event on queue
|
||||
|
@ -462,28 +455,25 @@ void CL_PlaybackEvent( int flags, const edict_t *pInvoker, word eventindex, floa
|
|||
{
|
||||
event_args_t args;
|
||||
|
||||
if( flags & FEV_SERVER )
|
||||
{
|
||||
MsgDev( D_WARN, "CL_PlaybackEvent: event with FEV_SERVER flag!\n" );
|
||||
if( FBitSet( flags, FEV_SERVER ))
|
||||
return;
|
||||
}
|
||||
|
||||
// first check event for out of bounds
|
||||
if( eventindex < 1 || eventindex > MAX_EVENTS )
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_PlaybackEvent: invalid eventindex %i\n", eventindex );
|
||||
Con_DPrintf( S_ERROR "CL_PlaybackEvent: invalid eventindex %i\n", eventindex );
|
||||
return;
|
||||
}
|
||||
|
||||
// check event for precached
|
||||
if( !CL_EventIndex( cl.event_precache[eventindex] ))
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_PlaybackEvent: event %i was not precached\n", eventindex );
|
||||
Con_DPrintf( S_ERROR "CL_PlaybackEvent: event %i was not precached\n", eventindex );
|
||||
return;
|
||||
}
|
||||
|
||||
flags |= FEV_CLIENT; // it's a client event
|
||||
flags &= ~(FEV_NOTHOST|FEV_HOSTONLY|FEV_GLOBAL);
|
||||
SetBits( flags, FEV_CLIENT ); // it's a client event
|
||||
ClearBits( flags, FEV_NOTHOST|FEV_HOSTONLY|FEV_GLOBAL );
|
||||
if( delay < 0.0f ) delay = 0.0f; // fixup negative delays
|
||||
|
||||
memset( &args, 0, sizeof( args ));
|
||||
|
|
|
@ -96,7 +96,7 @@ we don't want interpolate this
|
|||
*/
|
||||
qboolean CL_EntityTeleported( cl_entity_t *ent )
|
||||
{
|
||||
int len, maxlen;
|
||||
float len, maxlen;
|
||||
vec3_t delta;
|
||||
|
||||
VectorSubtract( ent->curstate.origin, ent->prevstate.origin, delta );
|
||||
|
@ -270,7 +270,7 @@ void CL_ProcessEntityUpdate( cl_entity_t *ent )
|
|||
ent->model = CL_ModelHandle( ent->curstate.modelindex );
|
||||
ent->index = ent->curstate.number;
|
||||
|
||||
// g-cont. make sure what it's no broke XashXT physics
|
||||
if( FBitSet( ent->curstate.entityType, ENTITY_NORMAL ))
|
||||
COM_NormalizeAngles( ent->curstate.angles );
|
||||
|
||||
parametric = CL_ParametricMove( ent );
|
||||
|
@ -410,8 +410,19 @@ int CL_InterpolateModel( cl_entity_t *e )
|
|||
if( cls.timedemo || !e->model )
|
||||
return 1;
|
||||
|
||||
if( fabs( cl_serverframetime() - cl_clientframetime()) < 0.0001f )
|
||||
return 1; // interpolation disabled
|
||||
if( cls.demoplayback == DEMO_QUAKE1 )
|
||||
{
|
||||
// quake lerping is easy
|
||||
VectorLerp( e->prevstate.origin, cl.lerpFrac, e->curstate.origin, e->origin );
|
||||
AngleQuaternion( e->prevstate.angles, q1, false );
|
||||
AngleQuaternion( e->curstate.angles, q2, false );
|
||||
QuaternionSlerp( q1, q2, cl.lerpFrac, q );
|
||||
QuaternionAngle( q, e->angles );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( cl.maxclients <= 1 )
|
||||
return 1;
|
||||
|
||||
if( e->model->type == mod_brush && !cl_bmodelinterp->value )
|
||||
return 1;
|
||||
|
@ -419,7 +430,6 @@ int CL_InterpolateModel( cl_entity_t *e )
|
|||
if( cl.local.moving && cl.local.onground == e->index )
|
||||
return 1;
|
||||
|
||||
// t = cl.time - cl_serverframetime();
|
||||
t = cl.time - cl_interp->value;
|
||||
CL_FindInterpolationUpdates( e, t, &ph0, &ph1 );
|
||||
|
||||
|
@ -478,12 +488,24 @@ interpolate non-local clients
|
|||
void CL_ComputePlayerOrigin( cl_entity_t *ent )
|
||||
{
|
||||
float targettime;
|
||||
vec4_t q, q1, q2;
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
|
||||
if( !ent->player || ent->index == ( cl.playernum + 1 ))
|
||||
return;
|
||||
|
||||
if( cls.demoplayback == DEMO_QUAKE1 )
|
||||
{
|
||||
// quake lerping is easy
|
||||
VectorLerp( ent->prevstate.origin, cl.lerpFrac, ent->curstate.origin, ent->origin );
|
||||
AngleQuaternion( ent->prevstate.angles, q1, false );
|
||||
AngleQuaternion( ent->curstate.angles, q2, false );
|
||||
QuaternionSlerp( q1, q2, cl.lerpFrac, q );
|
||||
QuaternionAngle( q, ent->angles );
|
||||
return;
|
||||
}
|
||||
|
||||
targettime = cl.time - cl_interp->value;
|
||||
CL_PureOrigin( ent, targettime, origin, angles );
|
||||
|
||||
|
@ -603,13 +625,13 @@ void CL_FlushEntityPacket( sizebuf_t *msg )
|
|||
// read it all, but ignore it
|
||||
while( 1 )
|
||||
{
|
||||
newnum = MSG_ReadUBitLong( msg, MAX_VISIBLE_PACKET_BITS );
|
||||
newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
|
||||
if( newnum == LAST_EDICT ) break; // done
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
Host_Error( "CL_FlushEntityPacket: overflow\n" );
|
||||
|
||||
MSG_ReadDeltaEntity( msg, &from, &to, newnum, CL_IsPlayerIndex( newnum ), cl.mtime[0] );
|
||||
MSG_ReadDeltaEntity( msg, &from, &to, newnum, CL_IsPlayerIndex( newnum ) ? DELTA_PLAYER : DELTA_ENTITY, cl.mtime[0] );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -626,17 +648,18 @@ void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t
|
|||
entity_state_t *state;
|
||||
qboolean newent = (old) ? false : true;
|
||||
int pack = frame->num_entities;
|
||||
qboolean player = CL_IsPlayerIndex( newnum );
|
||||
int delta_type = DELTA_ENTITY;
|
||||
qboolean alive = true;
|
||||
|
||||
// alloc next slot to store update
|
||||
state = &cls.packet_entities[cls.next_client_entities % cls.num_client_entities];
|
||||
if( CL_IsPlayerIndex( newnum )) delta_type = DELTA_PLAYER;
|
||||
|
||||
if(( newnum < 0 ) || ( newnum >= clgame.maxEntities ))
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_DeltaEntity: invalid newnum: %d\n", newnum );
|
||||
Con_DPrintf( S_ERROR "CL_DeltaEntity: invalid newnum: %d\n", newnum );
|
||||
if( has_update )
|
||||
MSG_ReadDeltaEntity( msg, old, state, newnum, player, cl.mtime[0] );
|
||||
MSG_ReadDeltaEntity( msg, old, state, newnum, delta_type, cl.mtime[0] );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -645,7 +668,7 @@ void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t
|
|||
if( newent ) old = &ent->baseline;
|
||||
|
||||
if( has_update )
|
||||
alive = MSG_ReadDeltaEntity( msg, old, state, newnum, player, cl.mtime[0] );
|
||||
alive = MSG_ReadDeltaEntity( msg, old, state, newnum, delta_type, cl.mtime[0] );
|
||||
else memcpy( state, old, sizeof( entity_state_t ));
|
||||
|
||||
if( !alive )
|
||||
|
@ -698,7 +721,10 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta )
|
|||
CL_WriteDemoJumpTime();
|
||||
|
||||
// sentinel count. save it for debug checking
|
||||
count = ( MSG_ReadUBitLong( msg, MAX_VISIBLE_PACKET_BITS ) + 1 );
|
||||
if( cls.legacymode )
|
||||
count = MSG_ReadWord( msg );
|
||||
else count = MSG_ReadUBitLong( msg, MAX_VISIBLE_PACKET_BITS ) + 1;
|
||||
|
||||
newframe = &cl.frames[cl.parsecountmod];
|
||||
|
||||
// allocate parse entities
|
||||
|
@ -733,7 +759,6 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta )
|
|||
|
||||
if(( cls.next_client_entities - oldframe->first_entity ) > ( cls.num_client_entities - NUM_PACKET_ENTITIES ))
|
||||
{
|
||||
MsgDev( D_NOTE, "CL_ParsePacketEntities: delta frame is too old (flush)\n");
|
||||
Con_NPrintf( 2, "^3Warning:^1 delta frame is too old^7\n" );
|
||||
CL_FlushEntityPacket( msg );
|
||||
return playerbytes;
|
||||
|
@ -772,10 +797,20 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta )
|
|||
}
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
int lastedict;
|
||||
if( cls.legacymode )
|
||||
{
|
||||
newnum = MSG_ReadWord( msg );
|
||||
lastedict = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
|
||||
if( newnum == LAST_EDICT ) break; // end of packet entities
|
||||
lastedict = LAST_EDICT;
|
||||
}
|
||||
|
||||
if( newnum == lastedict ) break; // end of packet entities
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
Host_Error( "CL_ParsePacketEntities: overflow\n" );
|
||||
player = CL_IsPlayerIndex( newnum );
|
||||
|
@ -846,7 +881,7 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta )
|
|||
}
|
||||
|
||||
if( newframe->num_entities != count && newframe->num_entities != 0 )
|
||||
MsgDev( D_WARN, "CL_Parse%sPacketEntities: (%i should be %i)\n", delta ? "Delta" : "", newframe->num_entities, count );
|
||||
Con_Reportf( S_WARN "CL_Parse%sPacketEntities: (%i should be %i)\n", delta ? "Delta" : "", newframe->num_entities, count );
|
||||
|
||||
if( !newframe->valid )
|
||||
return playerbytes; // frame is not valid but message was parsed
|
||||
|
@ -942,7 +977,7 @@ void CL_LinkCustomEntity( cl_entity_t *ent, entity_state_t *state )
|
|||
ent->curstate.movetype = state->modelindex; // !!!
|
||||
|
||||
if( ent->model->type != mod_sprite )
|
||||
MsgDev( D_WARN, "bad model on beam ( %s )\n", ent->model->name );
|
||||
Con_Reportf( S_WARN "bad model on beam ( %s )\n", ent->model->name );
|
||||
|
||||
ent->latched.prevsequence = ent->curstate.sequence;
|
||||
VectorCopy( ent->origin, ent->latched.prevorigin );
|
||||
|
@ -988,10 +1023,13 @@ void CL_LinkPlayers( frame_t *frame )
|
|||
if( ent->index != ( i + 1 )) ent->index = (i + 1);
|
||||
|
||||
if( i == cl.playernum )
|
||||
{
|
||||
if( cls.demoplayback != DEMO_QUAKE1 )
|
||||
{
|
||||
VectorCopy( state->origin, ent->origin );
|
||||
VectorCopy( state->origin, ent->prevstate.origin );
|
||||
VectorCopy( state->origin, ent->curstate.origin );
|
||||
}
|
||||
VectorCopy( ent->curstate.angles, ent->angles );
|
||||
}
|
||||
|
||||
|
@ -1007,6 +1045,8 @@ void CL_LinkPlayers( frame_t *frame )
|
|||
|
||||
if ( i == cl.playernum )
|
||||
{
|
||||
if( cls.demoplayback == DEMO_QUAKE1 )
|
||||
VectorLerp( ent->prevstate.origin, cl.lerpFrac, ent->curstate.origin, cl.simorg );
|
||||
VectorCopy( cl.simorg, ent->origin );
|
||||
}
|
||||
else
|
||||
|
@ -1041,6 +1081,7 @@ void CL_LinkPacketEntities( frame_t *frame )
|
|||
cl_entity_t *ent;
|
||||
entity_state_t *state;
|
||||
qboolean parametric;
|
||||
qboolean interpolate;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < frame->num_entities; i++ )
|
||||
|
@ -1059,22 +1100,21 @@ void CL_LinkPacketEntities( frame_t *frame )
|
|||
|
||||
if( !ent )
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_LinkPacketEntity: bad entity %i\n", state->number );
|
||||
Con_Reportf( S_ERROR "CL_LinkPacketEntity: bad entity %i\n", state->number );
|
||||
continue;
|
||||
}
|
||||
|
||||
ent->curstate = *state;
|
||||
|
||||
// XASH SPECIFIC
|
||||
if( ent->curstate.rendermode == kRenderNormal && ent->curstate.renderfx == kRenderFxNone )
|
||||
ent->curstate.renderamt = 255.0f;
|
||||
// animtime must keep an actual
|
||||
ent->curstate.animtime = state->animtime;
|
||||
ent->curstate.frame = state->frame;
|
||||
interpolate = false;
|
||||
|
||||
if( !ent->model ) continue;
|
||||
|
||||
if( ent->curstate.rendermode == kRenderNormal )
|
||||
{
|
||||
// auto 'solid' faces
|
||||
if( FBitSet( ent->model->flags, MODEL_TRANSPARENT ) && FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
if( FBitSet( ent->model->flags, MODEL_TRANSPARENT ) && Host_IsQuakeCompatible( ))
|
||||
{
|
||||
ent->curstate.rendermode = kRenderTransAlpha;
|
||||
ent->curstate.renderamt = 255;
|
||||
|
@ -1095,7 +1135,9 @@ void CL_LinkPacketEntities( frame_t *frame )
|
|||
#ifdef STUDIO_INTERPOLATION_FIX
|
||||
if( ent->lastmove >= cl.time )
|
||||
VectorCopy( ent->curstate.origin, ent->latched.prevorigin );
|
||||
ent->curstate.movetype = MOVETYPE_STEP;
|
||||
if( FBitSet( host.features, ENGINE_COMPUTE_STUDIO_LERP ))
|
||||
interpolate = true;
|
||||
else ent->curstate.movetype = MOVETYPE_STEP;
|
||||
#else
|
||||
if( ent->lastmove >= cl.time )
|
||||
{
|
||||
|
@ -1148,7 +1190,7 @@ void CL_LinkPacketEntities( frame_t *frame )
|
|||
|
||||
if( ent->model->type == mod_studio )
|
||||
{
|
||||
if( ent->curstate.movetype == MOVETYPE_STEP && FBitSet( host.features, ENGINE_COMPUTE_STUDIO_LERP ))
|
||||
if( interpolate && FBitSet( host.features, ENGINE_COMPUTE_STUDIO_LERP ))
|
||||
R_StudioLerpMovement( ent, cl.time, ent->origin, ent->angles );
|
||||
}
|
||||
}
|
||||
|
@ -1166,6 +1208,10 @@ void CL_LinkPacketEntities( frame_t *frame )
|
|||
ent->curstate.rendercolor.r = ent->curstate.rendercolor.g = ent->curstate.rendercolor.b = 255;
|
||||
}
|
||||
|
||||
// XASH SPECIFIC
|
||||
if( ent->curstate.rendermode == kRenderNormal && ent->curstate.renderfx == kRenderFxNone )
|
||||
ent->curstate.renderamt = 255.0f;
|
||||
|
||||
if( ent->curstate.aiment != 0 && ent->curstate.movetype != MOVETYPE_COMPOUND )
|
||||
ent->curstate.movetype = MOVETYPE_FOLLOW;
|
||||
|
||||
|
@ -1226,6 +1272,12 @@ void CL_EmitEntities( void )
|
|||
if( !cl.frames[cl.parsecountmod].valid )
|
||||
return;
|
||||
|
||||
// animate lightestyles
|
||||
CL_RunLightStyles ();
|
||||
|
||||
// decay dynamic lights
|
||||
CL_DecayLights ();
|
||||
|
||||
// compute last interpolation amount
|
||||
CL_UpdateFrameLerp ();
|
||||
|
||||
|
@ -1313,8 +1365,25 @@ qboolean CL_GetEntitySpatialization( channel_t *ch )
|
|||
|
||||
qboolean CL_GetMovieSpatialization( rawchan_t *ch )
|
||||
{
|
||||
// UNDONE
|
||||
return false;
|
||||
cl_entity_t *ent;
|
||||
qboolean valid_origin;
|
||||
|
||||
valid_origin = VectorIsNull( ch->origin ) ? false : true;
|
||||
ent = CL_GetEntityByIndex( ch->entnum );
|
||||
|
||||
// entity is not present on the client but has valid origin
|
||||
if( !ent || !ent->index || ent->curstate.messagenum == 0 )
|
||||
return valid_origin;
|
||||
|
||||
// setup origin
|
||||
VectorAverage( ent->curstate.mins, ent->curstate.maxs, ch->origin );
|
||||
VectorAdd( ch->origin, ent->curstate.origin, ch->origin );
|
||||
|
||||
// setup radius
|
||||
if( ent->model != NULL && ent->model->radius ) ch->radius = ent->model->radius;
|
||||
else ch->radius = RadiusFromBounds( ent->curstate.mins, ent->curstate.maxs );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CL_ExtraUpdate( void )
|
||||
|
|
|
@ -29,9 +29,7 @@ GNU General Public License for more details.
|
|||
#include "library.h"
|
||||
#include "vgui_draw.h"
|
||||
#include "sound.h" // SND_STOP_LOOPING
|
||||
#ifdef XASH_SDL
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
#include "platform/platform.h"
|
||||
|
||||
#define MAX_LINELENGTH 80
|
||||
#define MAX_TEXTCHANNELS 8 // must be power of two (GoldSrc uses 4 channels)
|
||||
|
@ -243,7 +241,7 @@ void CL_InitCDAudio( const char *filename )
|
|||
|
||||
if( ++c > MAX_CDTRACKS - 1 )
|
||||
{
|
||||
MsgDev( D_WARN, "CD_Init: too many tracks %i in %s\n", MAX_CDTRACKS, filename );
|
||||
Con_Reportf( S_WARN "CD_Init: too many tracks %i in %s\n", MAX_CDTRACKS, filename );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -832,14 +830,14 @@ const char *CL_SoundFromIndex( int index )
|
|||
|
||||
if( !hSound )
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_SoundFromIndex: invalid sound index %i\n", index );
|
||||
Con_DPrintf( S_ERROR "CL_SoundFromIndex: invalid sound index %i\n", index );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sfx = S_GetSfxByHandle( hSound );
|
||||
if( !sfx )
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_SoundFromIndex: bad sfx for index %i\n", index );
|
||||
Con_DPrintf( S_ERROR "CL_SoundFromIndex: bad sfx for index %i\n", index );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1065,7 +1063,7 @@ void CL_LinkUserMessage( char *pszName, const int svc_num, int iSize )
|
|||
for( i = 0; i < MAX_USER_MESSAGES && clgame.msg[i].name[0]; i++ )
|
||||
{
|
||||
// NOTE: no check for DispatchFunc, check only name
|
||||
if( !Q_strcmp( clgame.msg[i].name, pszName ))
|
||||
if( !Q_stricmp( clgame.msg[i].name, pszName ))
|
||||
{
|
||||
clgame.msg[i].number = svc_num;
|
||||
clgame.msg[i].size = iSize;
|
||||
|
@ -1115,16 +1113,16 @@ void CL_InitEdicts( void )
|
|||
|
||||
CL_UPDATE_BACKUP = ( cl.maxclients == 1 ) ? SINGLEPLAYER_BACKUP : MULTIPLAYER_BACKUP;
|
||||
cls.num_client_entities = CL_UPDATE_BACKUP * NUM_PACKET_ENTITIES;
|
||||
cls.packet_entities = Z_Realloc( cls.packet_entities, sizeof( entity_state_t ) * cls.num_client_entities );
|
||||
clgame.entities = Mem_Alloc( clgame.mempool, sizeof( cl_entity_t ) * clgame.maxEntities );
|
||||
clgame.static_entities = Mem_Alloc( clgame.mempool, sizeof( cl_entity_t ) * MAX_STATIC_ENTITIES );
|
||||
cls.packet_entities = Mem_Realloc( clgame.mempool, cls.packet_entities, sizeof( entity_state_t ) * cls.num_client_entities );
|
||||
clgame.entities = Mem_Calloc( clgame.mempool, sizeof( cl_entity_t ) * clgame.maxEntities );
|
||||
clgame.static_entities = Mem_Calloc( clgame.mempool, sizeof( cl_entity_t ) * MAX_STATIC_ENTITIES );
|
||||
clgame.numStatics = 0;
|
||||
|
||||
if(( clgame.maxRemapInfos - 1 ) != clgame.maxEntities )
|
||||
{
|
||||
CL_ClearAllRemaps (); // purge old remap info
|
||||
clgame.maxRemapInfos = clgame.maxEntities + 1;
|
||||
clgame.remap_info = (remap_info_t **)Mem_Alloc( clgame.mempool, sizeof( remap_info_t* ) * clgame.maxRemapInfos );
|
||||
clgame.remap_info = (remap_info_t **)Mem_Calloc( clgame.mempool, sizeof( remap_info_t* ) * clgame.maxRemapInfos );
|
||||
}
|
||||
|
||||
if( clgame.drawFuncs.R_ProcessEntData != NULL )
|
||||
|
@ -1217,6 +1215,7 @@ static qboolean CL_LoadHudSprite( const char *szSpriteName, model_t *m_pSprite,
|
|||
}
|
||||
else
|
||||
{
|
||||
Con_Reportf( S_ERROR "%s couldn't load\n", szSpriteName );
|
||||
Mod_UnloadSpriteModel( m_pSprite );
|
||||
return false;
|
||||
}
|
||||
|
@ -1258,7 +1257,7 @@ static model_t *CL_LoadSpriteModel( const char *filename, uint type, uint texFla
|
|||
|
||||
if( !COM_CheckString( filename ))
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_LoadSpriteModel: bad name!\n" );
|
||||
Con_Reportf( S_ERROR "CL_LoadSpriteModel: bad name!\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1535,7 +1534,7 @@ static client_sprite_t *pfnSPR_GetList( char *psz, int *piCount )
|
|||
Q_strncpy( pEntry->szListName, psz, sizeof( pEntry->szListName ));
|
||||
|
||||
// name, res, pic, x, y, w, h
|
||||
pEntry->pList = Mem_Alloc( cls.mempool, sizeof( client_sprite_t ) * numSprites );
|
||||
pEntry->pList = Mem_Calloc( cls.mempool, sizeof( client_sprite_t ) * numSprites );
|
||||
|
||||
for( index = 0; index < numSprites; index++ )
|
||||
{
|
||||
|
@ -1584,12 +1583,14 @@ CL_FillRGBA
|
|||
*/
|
||||
void CL_FillRGBA( int x, int y, int w, int h, int r, int g, int b, int a )
|
||||
{
|
||||
float _x = x, _y = y, _w = w, _h = h;
|
||||
|
||||
r = bound( 0, r, 255 );
|
||||
g = bound( 0, g, 255 );
|
||||
b = bound( 0, b, 255 );
|
||||
a = bound( 0, a, 255 );
|
||||
|
||||
SPR_AdjustSize( (float *)&x, (float *)&y, (float *)&w, (float *)&h );
|
||||
SPR_AdjustSize( &_x, &_y, &_w, &_h );
|
||||
|
||||
pglDisable( GL_TEXTURE_2D );
|
||||
pglEnable( GL_BLEND );
|
||||
|
@ -1598,10 +1599,10 @@ void CL_FillRGBA( int x, int y, int w, int h, int r, int g, int b, int a )
|
|||
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 );
|
||||
pglVertex2f( _x, _y );
|
||||
pglVertex2f( _x + _w, _y );
|
||||
pglVertex2f( _x + _w, _y + _h );
|
||||
pglVertex2f( _x, _y + _h );
|
||||
pglEnd ();
|
||||
|
||||
pglColor3f( 1.0f, 1.0f, 1.0f );
|
||||
|
@ -1682,7 +1683,7 @@ static int pfnHookUserMsg( const char *pszName, pfnUserMsgHook pfn )
|
|||
for( i = 0; i < MAX_USER_MESSAGES && clgame.msg[i].name[0]; i++ )
|
||||
{
|
||||
// see if already hooked
|
||||
if( !Q_strcmp( clgame.msg[i].name, pszName ))
|
||||
if( !Q_stricmp( clgame.msg[i].name, pszName ))
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1709,7 +1710,7 @@ static int pfnServerCmd( const char *szCmdString )
|
|||
{
|
||||
string buf;
|
||||
|
||||
if( !szCmdString || !szCmdString[0] )
|
||||
if( !COM_CheckString( szCmdString ))
|
||||
return 0;
|
||||
|
||||
// just like the client typed "cmd xxxxx" at the console
|
||||
|
@ -1727,11 +1728,20 @@ pfnClientCmd
|
|||
*/
|
||||
static int pfnClientCmd( const char *szCmdString )
|
||||
{
|
||||
if( !szCmdString || !szCmdString[0] )
|
||||
if( !COM_CheckString( szCmdString ))
|
||||
return 0;
|
||||
|
||||
if( cls.initialized )
|
||||
{
|
||||
Cbuf_AddText( szCmdString );
|
||||
Cbuf_AddText( "\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// will exec later
|
||||
Q_strncat( host.deferred_cmd, va( "%s\n", szCmdString ), sizeof( host.deferred_cmd ));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1790,12 +1800,8 @@ static void pfnPlaySoundByIndex( int iSound, float volume )
|
|||
// make sure what we in-bounds
|
||||
iSound = bound( 0, iSound, MAX_SOUNDS );
|
||||
hSound = cl.sound_index[iSound];
|
||||
if( !hSound ) return;
|
||||
|
||||
if( !hSound )
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_PlaySoundByIndex: invalid sound handle %i\n", iSound );
|
||||
return;
|
||||
}
|
||||
S_StartSound( NULL, cl.viewentity, CHAN_ITEM, hSound, volume, ATTN_NORM, PITCH_NORM, SND_STOP_LOOPING );
|
||||
}
|
||||
|
||||
|
@ -1866,7 +1872,8 @@ int pfnDrawConsoleString( int x, int y, char *string )
|
|||
{
|
||||
int drawLen;
|
||||
|
||||
if( !string || !*string ) return 0; // silent ignore
|
||||
if( !COM_CheckString( string ))
|
||||
return 0; // silent ignore
|
||||
Con_SetFont( con_fontsize->value );
|
||||
|
||||
clgame.ds.adjust_size = true;
|
||||
|
@ -1942,7 +1949,21 @@ GetWindowCenterX
|
|||
*/
|
||||
static int pfnGetWindowCenterX( void )
|
||||
{
|
||||
return host.window_center_x;
|
||||
int x = 0;
|
||||
#ifdef _WIN32
|
||||
if( m_ignore->value )
|
||||
{
|
||||
POINT pos;
|
||||
GetCursorPos( &pos );
|
||||
return pos.x;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef XASH_SDL
|
||||
SDL_GetWindowPosition( host.hWnd, &x, NULL );
|
||||
#endif
|
||||
|
||||
return host.window_center_x + x;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1953,7 +1974,21 @@ GetWindowCenterY
|
|||
*/
|
||||
static int pfnGetWindowCenterY( void )
|
||||
{
|
||||
return host.window_center_y;
|
||||
int y = 0;
|
||||
#ifdef _WIN32
|
||||
if( m_ignore->value )
|
||||
{
|
||||
POINT pos;
|
||||
GetCursorPos( &pos );
|
||||
return pos.y;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef XASH_SDL
|
||||
SDL_GetWindowPosition( host.hWnd, NULL, &y );
|
||||
#endif
|
||||
|
||||
return host.window_center_y + y;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2014,22 +2049,6 @@ static float pfnGetClientMaxspeed( void )
|
|||
return cl.local.maxspeed;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CL_GetMousePosition
|
||||
|
||||
=============
|
||||
*/
|
||||
void CL_GetMousePosition( int *mx, int *my )
|
||||
{
|
||||
#ifdef XASH_SDL
|
||||
SDL_GetMouseState( mx, my );
|
||||
#else
|
||||
if( mx ) *mx = 0;
|
||||
if( my ) *my = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
pfnIsNoClipping
|
||||
|
@ -2239,7 +2258,7 @@ static void pfnHookEvent( const char *filename, pfnEventHook pfn )
|
|||
|
||||
if( !Q_stricmp( name, ev->name ) && ev->func != NULL )
|
||||
{
|
||||
MsgDev( D_WARN, "CL_HookEvent: %s already hooked!\n", name );
|
||||
Con_Reportf( S_WARN "CL_HookEvent: %s already hooked!\n", name );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2720,7 +2739,7 @@ pfnServerCmdUnreliable
|
|||
*/
|
||||
int pfnServerCmdUnreliable( char *szCmdString )
|
||||
{
|
||||
if( !szCmdString || !szCmdString[0] )
|
||||
if( !COM_CheckString( szCmdString ))
|
||||
return 0;
|
||||
|
||||
MSG_BeginClientCmd( &cls.datagram, clc_stringcmd );
|
||||
|
@ -2740,20 +2759,7 @@ void pfnGetMousePos( struct tagPOINT *ppt )
|
|||
if( !ppt )
|
||||
return;
|
||||
|
||||
CL_GetMousePosition( &ppt->x, &ppt->y );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
pfnSetMousePos
|
||||
|
||||
=============
|
||||
*/
|
||||
void pfnSetMousePos( int mx, int my )
|
||||
{
|
||||
#ifdef XASH_SDL
|
||||
SDL_WarpMouseInWindow( host.hWnd, mx, my );
|
||||
#endif
|
||||
Platform_GetMousePos( &ppt->x, &ppt->y );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2992,12 +2998,14 @@ pfnFillRGBABlend
|
|||
*/
|
||||
void GAME_EXPORT CL_FillRGBABlend( int x, int y, int w, int h, int r, int g, int b, int a )
|
||||
{
|
||||
float _x = x, _y = y, _w = w, _h = h;
|
||||
|
||||
r = bound( 0, r, 255 );
|
||||
g = bound( 0, g, 255 );
|
||||
b = bound( 0, b, 255 );
|
||||
a = bound( 0, a, 255 );
|
||||
|
||||
SPR_AdjustSize( (float *)&x, (float *)&y, (float *)&w, (float *)&h );
|
||||
SPR_AdjustSize( &_x, &_y, &_w, &_h );
|
||||
|
||||
pglDisable( GL_TEXTURE_2D );
|
||||
pglEnable( GL_BLEND );
|
||||
|
@ -3006,10 +3014,10 @@ void GAME_EXPORT CL_FillRGBABlend( int x, int y, int w, int h, int r, int g, int
|
|||
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 );
|
||||
pglVertex2f( _x, _y );
|
||||
pglVertex2f( _x + _w, _y );
|
||||
pglVertex2f( _x + _w, _y + _h );
|
||||
pglVertex2f( _x, _y + _h );
|
||||
pglEnd ();
|
||||
|
||||
pglColor3f( 1.0f, 1.0f, 1.0f );
|
||||
|
@ -3525,7 +3533,7 @@ void NetAPI_SendRequest( int context, int request, int flags, double timeout, ne
|
|||
|
||||
if( !response )
|
||||
{
|
||||
MsgDev( D_ERROR, "Net_SendRequest: no callbcak specified for request with context %i!\n", context );
|
||||
Con_DPrintf( S_ERROR "Net_SendRequest: no callbcak specified for request with context %i!\n", context );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3908,6 +3916,8 @@ static event_api_t gEventApi =
|
|||
CL_VisTraceLine,
|
||||
pfnGetVisent,
|
||||
CL_TestLine,
|
||||
CL_PushTraceBounds,
|
||||
CL_PopTraceBounds,
|
||||
};
|
||||
|
||||
static demo_api_t gDemoApi =
|
||||
|
@ -3993,7 +4003,7 @@ static cl_enginefunc_t gEngfuncs =
|
|||
pfnGetClientMaxspeed,
|
||||
COM_CheckParm,
|
||||
Key_Event,
|
||||
CL_GetMousePosition,
|
||||
Platform_GetMousePos,
|
||||
pfnIsNoClipping,
|
||||
CL_GetLocalPlayer,
|
||||
pfnGetViewModel,
|
||||
|
@ -4043,7 +4053,7 @@ static cl_enginefunc_t gEngfuncs =
|
|||
pfnGetPlayerForTrackerID,
|
||||
pfnServerCmdUnreliable,
|
||||
pfnGetMousePos,
|
||||
pfnSetMousePos,
|
||||
Platform_SetMousePos,
|
||||
pfnSetMouseEnable,
|
||||
Cvar_GetList,
|
||||
(void*)Cmd_GetFirstFunctionHandle,
|
||||
|
@ -4139,7 +4149,7 @@ qboolean CL_LoadProgs( const char *name )
|
|||
// trying to get single export
|
||||
if(( GetClientAPI = (void *)COM_GetProcAddress( clgame.hInstance, "GetClientAPI" )) != NULL )
|
||||
{
|
||||
MsgDev( D_NOTE, "CL_LoadProgs: found single callback export\n" );
|
||||
Con_Reportf( "CL_LoadProgs: found single callback export\n" );
|
||||
|
||||
// trying to fill interface now
|
||||
GetClientAPI( &clgame.dllFuncs );
|
||||
|
@ -4164,7 +4174,7 @@ qboolean CL_LoadProgs( const char *name )
|
|||
// functions are cleared before all the extensions are evaluated
|
||||
if(( *func->func = (void *)COM_GetProcAddress( clgame.hInstance, func->name )) == NULL )
|
||||
{
|
||||
MsgDev( D_NOTE, "CL_LoadProgs: failed to get address of %s proc\n", func->name );
|
||||
Con_Reportf( "CL_LoadProgs: failed to get address of %s proc\n", func->name );
|
||||
|
||||
if( critical_exports )
|
||||
{
|
||||
|
@ -4191,13 +4201,13 @@ qboolean CL_LoadProgs( const char *name )
|
|||
// functions are cleared before all the extensions are evaluated
|
||||
// NOTE: new exports can be missed without stop the engine
|
||||
if(( *func->func = (void *)COM_GetProcAddress( clgame.hInstance, func->name )) == NULL )
|
||||
MsgDev( D_NOTE, "CL_LoadProgs: failed to get address of %s proc\n", func->name );
|
||||
Con_Reportf( "CL_LoadProgs: failed to get address of %s proc\n", func->name );
|
||||
}
|
||||
|
||||
if( !clgame.dllFuncs.pfnInitialize( &gEngfuncs, CLDLL_INTERFACE_VERSION ))
|
||||
{
|
||||
COM_FreeLibrary( clgame.hInstance );
|
||||
MsgDev( D_NOTE, "CL_LoadProgs: can't init client API\n" );
|
||||
Con_Reportf( "CL_LoadProgs: can't init client API\n" );
|
||||
clgame.hInstance = NULL;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,19 @@ void UI_UpdateMenu( float realtime )
|
|||
{
|
||||
if( !gameui.hInstance ) return;
|
||||
|
||||
// if some deferred cmds is waiting
|
||||
if( UI_IsVisible() && COM_CheckString( host.deferred_cmd ))
|
||||
{
|
||||
Cbuf_AddText( host.deferred_cmd );
|
||||
host.deferred_cmd[0] = '\0';
|
||||
Cbuf_Execute();
|
||||
return;
|
||||
}
|
||||
|
||||
// don't show menu while level is loaded
|
||||
if( GameState->nextstate != STATE_RUNFRAME && !GameState->loadGame )
|
||||
return;
|
||||
|
||||
// menu time (not paused, not clamped)
|
||||
gameui.globals->time = host.realtime;
|
||||
gameui.globals->frametime = host.realframetime;
|
||||
|
@ -148,7 +161,7 @@ static void UI_DrawLogo( const char *filename, float x, float y, float width, fl
|
|||
|
||||
if( FS_FileExists( path, false ) && !fullpath )
|
||||
{
|
||||
MsgDev( D_ERROR, "Couldn't load %s from packfile. Please extract it\n", path );
|
||||
Con_Printf( S_ERROR "Couldn't load %s from packfile. Please extract it\n", path );
|
||||
gameui.drawLogo = false;
|
||||
return;
|
||||
}
|
||||
|
@ -249,6 +262,8 @@ static void UI_ConvertGameInfo( GAMEINFO *out, gameinfo_t *in )
|
|||
|
||||
if( in->nomodels )
|
||||
out->flags |= GFL_NOMODELS;
|
||||
if( in->noskills )
|
||||
out->flags |= GFL_NOSKILLS;
|
||||
}
|
||||
|
||||
static qboolean PIC_Scissor( float *x, float *y, float *width, float *height, float *u0, float *v0, float *u1, float *v1 )
|
||||
|
@ -361,13 +376,13 @@ pfnPIC_Load
|
|||
|
||||
=========
|
||||
*/
|
||||
static HIMAGE pfnPIC_Load( const char *szPicName, const byte *image_buf, long image_size, long flags )
|
||||
static HIMAGE pfnPIC_Load( const char *szPicName, const byte *image_buf, int image_size, int flags )
|
||||
{
|
||||
HIMAGE tx;
|
||||
|
||||
if( !szPicName || !*szPicName )
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_LoadImage: bad name!\n" );
|
||||
Con_Reportf( S_ERROR "CL_LoadImage: bad name!\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -375,7 +390,7 @@ static HIMAGE pfnPIC_Load( const char *szPicName, const byte *image_buf, long im
|
|||
SetBits( flags, TF_IMAGE );
|
||||
|
||||
Image_SetForceFlags( IL_LOAD_DECAL ); // allow decal images for menu
|
||||
tx = GL_LoadTexture( szPicName, image_buf, image_size, flags, NULL );
|
||||
tx = GL_LoadTexture( szPicName, image_buf, image_size, flags );
|
||||
Image_ClearForceFlags();
|
||||
|
||||
return tx;
|
||||
|
@ -700,15 +715,19 @@ for drawing playermodel previews
|
|||
*/
|
||||
static void pfnRenderScene( const ref_viewpass_t *rvp )
|
||||
{
|
||||
ref_viewpass_t copy;
|
||||
|
||||
// to avoid division by zero
|
||||
if( !rvp || rvp->fov_x <= 0.0f || rvp->fov_y <= 0.0f )
|
||||
return;
|
||||
|
||||
copy = *rvp;
|
||||
|
||||
// don't allow special modes from menu
|
||||
((ref_viewpass_t *)&rvp)->flags = 0;
|
||||
copy.flags = 0;
|
||||
|
||||
R_Set2DMode( false );
|
||||
R_RenderFrame( rvp );
|
||||
R_RenderFrame( © );
|
||||
R_Set2DMode( true );
|
||||
R_PopScene();
|
||||
}
|
||||
|
@ -785,7 +804,7 @@ pfnMemAlloc
|
|||
*/
|
||||
static void *pfnMemAlloc( size_t cb, const char *filename, const int fileline )
|
||||
{
|
||||
return _Mem_Alloc( gameui.mempool, cb, filename, fileline );
|
||||
return _Mem_Alloc( gameui.mempool, cb, true, filename, fileline );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -886,7 +905,7 @@ int pfnCheckGameDll( void )
|
|||
COM_FreeLibrary( hInst ); // don't increase linker's reference counter
|
||||
return true;
|
||||
}
|
||||
MsgDev( D_WARN, "Could not load server library:\n%s", COM_GetLibraryError() );
|
||||
Con_Reportf( S_WARN "Could not load server library:\n%s", COM_GetLibraryError() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1080,7 +1099,7 @@ qboolean UI_LoadProgs( void )
|
|||
if(( GetMenuAPI = (MENUAPI)COM_GetProcAddress( gameui.hInstance, "GetMenuAPI" )) == NULL )
|
||||
{
|
||||
COM_FreeLibrary( gameui.hInstance );
|
||||
MsgDev( D_NOTE, "UI_LoadProgs: can't init menu API\n" );
|
||||
Con_Reportf( "UI_LoadProgs: can't init menu API\n" );
|
||||
gameui.hInstance = NULL;
|
||||
return false;
|
||||
}
|
||||
|
@ -1088,21 +1107,6 @@ qboolean UI_LoadProgs( void )
|
|||
|
||||
gameui.use_text_api = false;
|
||||
|
||||
if( ( GiveTextApi = (UITEXTAPI)COM_GetProcAddress( gameui.hInstance, "GiveTextAPI" ) ) )
|
||||
{
|
||||
MsgDev( D_NOTE, "UI_LoadProgs: extended Text API initialized\n" );
|
||||
// make local copy of engfuncs to prevent overwrite it with user dll
|
||||
memcpy( &gpTextfuncs, &gTextfuncs, sizeof( gpTextfuncs ));
|
||||
if( GiveTextApi( &gpTextfuncs ) )
|
||||
gameui.use_text_api = true;
|
||||
}
|
||||
|
||||
pfnAddTouchButtonToList = (ADDTOUCHBUTTONTOLIST)COM_GetProcAddress( gameui.hInstance, "AddTouchButtonToList" );
|
||||
if( pfnAddTouchButtonToList )
|
||||
{
|
||||
MsgDev( D_NOTE, "UI_LoadProgs: AddTouchButtonToList call found\n" );
|
||||
}
|
||||
|
||||
// make local copy of engfuncs to prevent overwrite it with user dll
|
||||
memcpy( &gpEngfuncs, &gEngfuncs, sizeof( gpEngfuncs ));
|
||||
|
||||
|
@ -1111,18 +1115,33 @@ qboolean UI_LoadProgs( void )
|
|||
if( !GetMenuAPI( &gameui.dllFuncs, &gpEngfuncs, gameui.globals ))
|
||||
{
|
||||
COM_FreeLibrary( gameui.hInstance );
|
||||
MsgDev( D_NOTE, "UI_LoadProgs: can't init menu API\n" );
|
||||
Con_Reportf( "UI_LoadProgs: can't init menu API\n" );
|
||||
Mem_FreePool( &gameui.mempool );
|
||||
gameui.hInstance = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( ( GiveTextApi = (UITEXTAPI)COM_GetProcAddress( gameui.hInstance, "GiveTextAPI" ) ) )
|
||||
{
|
||||
Con_Reportf( "UI_LoadProgs: extended Text API initialized\n" );
|
||||
// make local copy of engfuncs to prevent overwrite it with user dll
|
||||
memcpy( &gpTextfuncs, &gTextfuncs, sizeof( gpTextfuncs ));
|
||||
if( GiveTextApi( &gpTextfuncs ) )
|
||||
gameui.use_text_api = true;
|
||||
}
|
||||
|
||||
pfnAddTouchButtonToList = (ADDTOUCHBUTTONTOLIST)COM_GetProcAddress( gameui.hInstance, "AddTouchButtonToList" );
|
||||
if( pfnAddTouchButtonToList )
|
||||
{
|
||||
Con_Reportf( "UI_LoadProgs: AddTouchButtonToList call found\n" );
|
||||
}
|
||||
|
||||
Cvar_FullSet( "host_gameuiloaded", "1", FCVAR_READ_ONLY );
|
||||
|
||||
// setup gameinfo
|
||||
for( i = 0; i < SI.numgames; i++ )
|
||||
{
|
||||
gameui.modsInfo[i] = Mem_Alloc( gameui.mempool, sizeof( GAMEINFO ));
|
||||
gameui.modsInfo[i] = Mem_Calloc( gameui.mempool, sizeof( GAMEINFO ));
|
||||
UI_ConvertGameInfo( gameui.modsInfo[i], SI.games[i] );
|
||||
}
|
||||
|
||||
|
|
|
@ -83,6 +83,8 @@ client_t cl;
|
|||
client_static_t cls;
|
||||
clgame_static_t clgame;
|
||||
|
||||
void CL_InternetServers_f( void );
|
||||
|
||||
//======================================================================
|
||||
int CL_Active( void )
|
||||
{
|
||||
|
@ -213,7 +215,7 @@ An svc_signonnum has been received, perform a client side setup
|
|||
void CL_SignonReply( void )
|
||||
{
|
||||
// g-cont. my favorite message :-)
|
||||
Con_DPrintf( "CL_SignonReply: %i\n", cls.signon );
|
||||
Con_Reportf( "CL_SignonReply: %i\n", cls.signon );
|
||||
|
||||
switch( cls.signon )
|
||||
{
|
||||
|
@ -247,14 +249,31 @@ static float CL_LerpPoint( void )
|
|||
if( f == 0.0f || cls.timedemo )
|
||||
{
|
||||
cl.time = cl.mtime[0];
|
||||
|
||||
// g-cont. probably this is redundant
|
||||
if( cls.demoplayback )
|
||||
cl.oldtime = cl.mtime[0] - cl_clientframetime();
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
if( f > 0.1f )
|
||||
{
|
||||
// dropped packet, or start of demo
|
||||
cl.mtime[1] = cl.mtime[0] - 0.1f;
|
||||
f = 0.1f;
|
||||
}
|
||||
#if 1
|
||||
frac = (cl.time - cl.mtime[1]) / f;
|
||||
|
||||
if( frac < 0.0f )
|
||||
{
|
||||
if( frac < -0.01 )
|
||||
cl.time = cl.mtime[1];
|
||||
frac = 0.0f;
|
||||
}
|
||||
else if( frac > 1.0f )
|
||||
{
|
||||
if( frac > 1.01 )
|
||||
cl.time = cl.mtime[0];
|
||||
frac = 1.0f;
|
||||
}
|
||||
#else
|
||||
if( cl_interp->value > 0.001f )
|
||||
{
|
||||
// manual lerp value (goldsrc mode)
|
||||
|
@ -265,7 +284,7 @@ static float CL_LerpPoint( void )
|
|||
// automatic lerp (classic mode)
|
||||
frac = ( cl.time - cl.mtime[1] ) / f;
|
||||
}
|
||||
|
||||
#endif
|
||||
return frac;
|
||||
}
|
||||
|
||||
|
@ -888,16 +907,10 @@ void CL_BeginUpload_f( void )
|
|||
name = Cmd_Argv( 1 );
|
||||
|
||||
if( !COM_CheckString( name ))
|
||||
{
|
||||
MsgDev( D_ERROR, "upload without filename\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !cl_allow_upload.value )
|
||||
{
|
||||
MsgDev( D_WARN, "ingoring decal upload ( cl_allow_upload is 0 )\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( Q_strlen( name ) != 36 || Q_strnicmp( name, "!MD5", 4 ))
|
||||
{
|
||||
|
@ -912,7 +925,7 @@ void CL_BeginUpload_f( void )
|
|||
{
|
||||
if( memcmp( md5, custResource.rgucMD5_hash, 16 ))
|
||||
{
|
||||
MsgDev( D_REPORT, "Bogus data retrieved from %s, attempting to delete entry\n", CUSTOM_RES_PATH );
|
||||
Con_Reportf( "Bogus data retrieved from %s, attempting to delete entry\n", CUSTOM_RES_PATH );
|
||||
HPAK_RemoveLump( CUSTOM_RES_PATH, &custResource );
|
||||
return;
|
||||
}
|
||||
|
@ -929,26 +942,22 @@ void CL_BeginUpload_f( void )
|
|||
|
||||
if( memcmp( custResource.rgucMD5_hash, md5, 16 ))
|
||||
{
|
||||
MsgDev( D_REPORT, "HPAK_AddLump called with bogus lump, md5 mismatch\n" );
|
||||
MsgDev( D_REPORT, "Purported: %s\n", MD5_Print( custResource.rgucMD5_hash ) );
|
||||
MsgDev( D_REPORT, "Actual : %s\n", MD5_Print( md5 ) );
|
||||
MsgDev( D_REPORT, "Removing conflicting lump\n" );
|
||||
Con_Reportf( "HPAK_AddLump called with bogus lump, md5 mismatch\n" );
|
||||
Con_Reportf( "Purported: %s\n", MD5_Print( custResource.rgucMD5_hash ) );
|
||||
Con_Reportf( "Actual : %s\n", MD5_Print( md5 ) );
|
||||
Con_Reportf( "Removing conflicting lump\n" );
|
||||
HPAK_RemoveLump( CUSTOM_RES_PATH, &custResource );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( buf && size )
|
||||
if( buf && size > 0 )
|
||||
{
|
||||
Netchan_CreateFileFragmentsFromBuffer( &cls.netchan, name, buf, size );
|
||||
Netchan_FragSend( &cls.netchan );
|
||||
Mem_Free( buf );
|
||||
}
|
||||
else
|
||||
{
|
||||
MsgDev( D_REPORT, "ingoring customization upload, couldn't find decal locally\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1003,10 +1012,40 @@ void CL_SendConnectPacket( void )
|
|||
key = ID_GetMD5();
|
||||
|
||||
memset( protinfo, 0, sizeof( protinfo ));
|
||||
|
||||
if( cls.legacymode )
|
||||
{
|
||||
// set related userinfo keys
|
||||
if( cl_dlmax->value >= 40000 || cl_dlmax->value < 100 )
|
||||
Cvar_FullSet( "cl_maxpacket", "1400", FCVAR_USERINFO );
|
||||
else
|
||||
Cvar_FullSet( "cl_maxpacket", cl_dlmax->string, FCVAR_USERINFO );
|
||||
Cvar_FullSet( "cl_maxpayload", "1000", FCVAR_USERINFO );
|
||||
|
||||
/// TODO: add input devices list
|
||||
//Info_SetValueForKey( protinfo, "d", va( "%d", input_devices ), sizeof( protinfo ) );
|
||||
Info_SetValueForKey( protinfo, "v", XASH_VERSION, sizeof( protinfo ) );
|
||||
Info_SetValueForKey( protinfo, "b", va( "%d", Q_buildnum() ), sizeof( protinfo ) );
|
||||
Info_SetValueForKey( protinfo, "o", Q_buildos(), sizeof( protinfo ) );
|
||||
Info_SetValueForKey( protinfo, "a", Q_buildarch(), sizeof( protinfo ) );
|
||||
Info_SetValueForKey( protinfo, "i", ID_GetMD5(), sizeof( protinfo ) );
|
||||
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "connect %i %i %i \"%s\" 2 \"%s\"\n",
|
||||
PROTOCOL_LEGACY_VERSION, Q_atoi( qport ), cls.challenge, cls.userinfo, protinfo );
|
||||
Con_Printf( "Trying to connect by legacy protocol\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove useless userinfo keys
|
||||
Cvar_FullSet( "cl_maxpacket", "0", 0 );
|
||||
Cvar_FullSet( "cl_maxpayload", "1000", 0 );
|
||||
Info_SetValueForKey( protinfo, "uuid", key, sizeof( protinfo ));
|
||||
Info_SetValueForKey( protinfo, "qport", qport, sizeof( protinfo ));
|
||||
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "connect %i %i \"%s\" \"%s\"\n", PROTOCOL_VERSION, cls.challenge, protinfo, cls.userinfo );
|
||||
Con_Printf( "Trying to connect by modern protocol\n" );
|
||||
}
|
||||
|
||||
|
||||
cls.timestart = Sys_DoubleTime();
|
||||
}
|
||||
|
||||
|
@ -1020,6 +1059,10 @@ Resend a connect message if the last one has timed out
|
|||
void CL_CheckForResend( void )
|
||||
{
|
||||
netadr_t adr;
|
||||
int res;
|
||||
|
||||
if( cls.internetservers_wait )
|
||||
CL_InternetServers_f();
|
||||
|
||||
// if the local server is running and we aren't then connect
|
||||
if( cls.state == ca_disconnected && SV_Active( ))
|
||||
|
@ -1044,17 +1087,24 @@ void CL_CheckForResend( void )
|
|||
if(( host.realtime - cls.connect_time ) < cl_resend.value )
|
||||
return;
|
||||
|
||||
if( !NET_StringToAdr( cls.servername, &adr ))
|
||||
res = NET_StringToAdrNB( cls.servername, &adr );
|
||||
|
||||
if( !res )
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_CheckForResend: bad server address\n" );
|
||||
CL_Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
if( res == 2 )
|
||||
{
|
||||
cls.connect_time = MAX_HEARTBEAT;
|
||||
return;
|
||||
}
|
||||
|
||||
// only retry so many times before failure.
|
||||
if( cls.connect_retry >= CL_CONNECTION_RETRIES )
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_CheckForResend: couldn't connected\n" );
|
||||
Con_DPrintf( S_ERROR "CL_CheckForResend: couldn't connected\n" );
|
||||
CL_Disconnect();
|
||||
return;
|
||||
}
|
||||
|
@ -1078,9 +1128,10 @@ void CL_CheckForResend( void )
|
|||
|
||||
Con_Printf( "Connecting to %s... [retry #%i]\n", cls.servername, cls.connect_retry );
|
||||
|
||||
if( cl_test_bandwidth.value )
|
||||
if( !cls.legacymode && cl_test_bandwidth.value )
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "bandwidth %i %i\n", PROTOCOL_VERSION, cls.max_fragment_size );
|
||||
else Netchan_OutOfBandPrint( NS_CLIENT, adr, "getchallenge\n" );
|
||||
else
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "getchallenge\n" );
|
||||
}
|
||||
|
||||
resource_t *CL_AddResource( resourcetype_t type, const char *name, int size, qboolean bFatalIfMissing, int index )
|
||||
|
@ -1145,8 +1196,14 @@ CL_Connect_f
|
|||
void CL_Connect_f( void )
|
||||
{
|
||||
string server;
|
||||
qboolean legacyconnect = false;
|
||||
|
||||
if( Cmd_Argc() != 2 )
|
||||
// hidden hint to connect by using legacy protocol
|
||||
if( Cmd_Argc() == 3 )
|
||||
{
|
||||
legacyconnect = !Q_strcmp( Cmd_Argv( 2 ), "legacy" );
|
||||
}
|
||||
else if( Cmd_Argc() != 2 )
|
||||
{
|
||||
Con_Printf( S_USAGE "connect <server>\n" );
|
||||
return;
|
||||
|
@ -1166,6 +1223,7 @@ void CL_Connect_f( void )
|
|||
Key_SetKeyDest( key_console );
|
||||
|
||||
cls.state = ca_connecting;
|
||||
cls.legacymode = legacyconnect;
|
||||
Q_strncpy( cls.servername, server, sizeof( cls.servername ));
|
||||
cls.connect_time = MAX_HEARTBEAT; // CL_CheckForResend() will fire immediately
|
||||
cls.max_fragment_size = FRAGMENT_MAX_SIZE; // guess a we can establish connection with maximum fragment size
|
||||
|
@ -1317,6 +1375,19 @@ void CL_Reconnect( qboolean setup_netchan )
|
|||
if( setup_netchan )
|
||||
{
|
||||
Netchan_Setup( NS_CLIENT, &cls.netchan, net_from, Cvar_VariableInteger( "net_qport" ), NULL, CL_GetFragmentSize );
|
||||
|
||||
if( cls.legacymode )
|
||||
{
|
||||
unsigned int extensions = Q_atoi( Cmd_Argv( 1 ) );
|
||||
|
||||
if( extensions & NET_EXT_SPLIT )
|
||||
{
|
||||
// only enable incoming split for legacy mode
|
||||
cls.netchan.split = true;
|
||||
Con_Reportf( "^2NET_EXT_SPLIT enabled^7 (packet sizes is %d/%d)\n", (int)cl_dlmax->value, 65536 );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1351,6 +1422,8 @@ This is also called on Host_Error, so it shouldn't cause any errors
|
|||
*/
|
||||
void CL_Disconnect( void )
|
||||
{
|
||||
cls.legacymode = false;
|
||||
|
||||
if( cls.state == ca_disconnected )
|
||||
return;
|
||||
|
||||
|
@ -1370,6 +1443,7 @@ void CL_Disconnect( void )
|
|||
Netchan_Clear( &cls.netchan );
|
||||
|
||||
cls.state = ca_disconnected;
|
||||
cls.set_lastdemo = false;
|
||||
cls.connect_retry = 0;
|
||||
cls.signon = 0;
|
||||
|
||||
|
@ -1424,6 +1498,8 @@ void CL_LocalServers_f( void )
|
|||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "info %i", PROTOCOL_VERSION );
|
||||
}
|
||||
|
||||
#define MS_SCAN_REQUEST "1\xFF" "0.0.0.0:0\0"
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_InternetServers_f
|
||||
|
@ -1431,23 +1507,27 @@ CL_InternetServers_f
|
|||
*/
|
||||
void CL_InternetServers_f( void )
|
||||
{
|
||||
netadr_t adr;
|
||||
char fullquery[512] = "1\xFF" "0.0.0.0:0\0" "\\gamedir\\";
|
||||
char fullquery[512] = MS_SCAN_REQUEST;
|
||||
char *info = fullquery + sizeof( MS_SCAN_REQUEST ) - 1;
|
||||
const size_t remaining = sizeof( fullquery ) - sizeof( MS_SCAN_REQUEST );
|
||||
|
||||
Con_Printf( "Scanning for servers on the internet area...\n" );
|
||||
NET_Config( true ); // allow remote
|
||||
|
||||
if( !NET_StringToAdr( MASTERSERVER_ADR, &adr ) )
|
||||
MsgDev( D_ERROR, "Can't resolve adr: %s\n", MASTERSERVER_ADR );
|
||||
Con_Printf( "Scanning for servers on the internet area...\n" );
|
||||
Info_SetValueForKey( info, "gamedir", GI->gamefolder, remaining );
|
||||
Info_SetValueForKey( info, "clver", XASH_VERSION, remaining ); // let master know about client version
|
||||
// Info_SetValueForKey( info, "nat", cl_nat->string, remaining );
|
||||
|
||||
Q_strcpy( &fullquery[22], GI->gamefolder );
|
||||
|
||||
NET_SendPacket( NS_CLIENT, Q_strlen( GI->gamefolder ) + 23, fullquery, adr );
|
||||
cls.internetservers_wait = NET_SendToMasters( NS_CLIENT, sizeof( MS_SCAN_REQUEST ) + Q_strlen( info ), fullquery );
|
||||
cls.internetservers_pending = true;
|
||||
|
||||
if( !cls.internetservers_wait )
|
||||
{
|
||||
// now we clearing the vgui request
|
||||
if( clgame.master_request != NULL )
|
||||
memset( clgame.master_request, 0, sizeof( net_request_t ));
|
||||
clgame.request_type = NET_REQUEST_GAMEUI;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1562,11 +1642,21 @@ void CL_ParseStatusMessage( netadr_t from, sizebuf_t *msg )
|
|||
|
||||
CL_FixupColorStringsForInfoString( s, infostring );
|
||||
|
||||
if( Q_strstr( infostring, "wrong version" ) )
|
||||
{
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, from, "info %i", PROTOCOL_LEGACY_VERSION );
|
||||
Con_Printf( "^1Server^7: %s, Info: %s\n", NET_AdrToString( from ), infostring );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !COM_CheckString( Info_ValueForKey( infostring, "gamedir" )))
|
||||
{
|
||||
Con_Printf( "^1Server^7: %s, Info: %s\n", NET_AdrToString( from ), infostring );
|
||||
return; // unsupported proto
|
||||
}
|
||||
|
||||
// more info about servers
|
||||
Con_Printf( "Server: %s, Game: %s\n", NET_AdrToString( from ), Info_ValueForKey( infostring, "gamedir" ));
|
||||
Con_Printf( "^2Server^7: %s, Game: %s\n", NET_AdrToString( from ), Info_ValueForKey( infostring, "gamedir" ));
|
||||
|
||||
UI_AddServerToList( from, infostring );
|
||||
}
|
||||
|
@ -1719,14 +1809,14 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
|||
Cmd_TokenizeString( args );
|
||||
c = Cmd_Argv( 0 );
|
||||
|
||||
MsgDev( D_NOTE, "CL_ConnectionlessPacket: %s : %s\n", NET_AdrToString( from ), c );
|
||||
Con_Reportf( "CL_ConnectionlessPacket: %s : %s\n", NET_AdrToString( from ), c );
|
||||
|
||||
// server connection
|
||||
if( !Q_strcmp( c, "client_connect" ))
|
||||
{
|
||||
if( cls.state == ca_connected )
|
||||
{
|
||||
MsgDev( D_ERROR, "dup connect received. ignored\n");
|
||||
Con_DPrintf( S_ERROR "dup connect received. ignored\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1764,6 +1854,14 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
|||
// print command from somewhere
|
||||
Con_Printf( "%s", MSG_ReadString( msg ));
|
||||
}
|
||||
else if( !Q_strcmp( c, "errormsg" ))
|
||||
{
|
||||
args = MSG_ReadString( msg );
|
||||
if( !Q_strcmp( args, "Server uses protocol version 48.\n" ))
|
||||
{
|
||||
cls.legacyserver = from;
|
||||
}
|
||||
}
|
||||
else if( !Q_strcmp( c, "testpacket" ))
|
||||
{
|
||||
byte recv_buf[NET_MAX_FRAGMENT];
|
||||
|
@ -1784,7 +1882,6 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
|||
}
|
||||
|
||||
// if we waiting more than cl_timeout or packet was trashed
|
||||
Msg( "got testpacket, size mismatched %d should be %d\n", MSG_GetMaxBytes( msg ), cls.max_fragment_size );
|
||||
cls.connect_time = MAX_HEARTBEAT;
|
||||
return; // just wait for a next responce
|
||||
}
|
||||
|
@ -1798,7 +1895,8 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
|||
if( crcValue == crcValue2 )
|
||||
{
|
||||
// packet was sucessfully delivered, adjust the fragment size and get challenge
|
||||
Msg( "CRC 0x%08x is matched, get challenge, fragment size %d\n", crcValue, cls.max_fragment_size );
|
||||
|
||||
Con_DPrintf( "CRC %x is matched, get challenge, fragment size %d\n", crcValue, cls.max_fragment_size );
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, from, "getchallenge\n" );
|
||||
Cvar_SetValue( "cl_dlmax", cls.max_fragment_size );
|
||||
cls.connect_time = host.realtime;
|
||||
|
@ -1816,6 +1914,7 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
|||
}
|
||||
|
||||
Msg( "got testpacket, CRC mismatched 0x%08x should be 0x%08x, trying next fragment size %d\n", crcValue2, crcValue, cls.max_fragment_size >> 1 );
|
||||
|
||||
// trying the next size of packet
|
||||
cls.connect_time = MAX_HEARTBEAT;
|
||||
}
|
||||
|
@ -1842,6 +1941,12 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
|||
// a disconnect message from the server, which will happen if the server
|
||||
// dropped the connection but it is still getting packets from us
|
||||
CL_Disconnect_f();
|
||||
|
||||
if( NET_CompareAdr( from, cls.legacyserver ))
|
||||
{
|
||||
Cbuf_AddText( va( "connect %s legacy\n", NET_AdrToString( from )));
|
||||
memset( &cls.legacyserver, 0, sizeof( cls.legacyserver ));
|
||||
}
|
||||
}
|
||||
else if( !Q_strcmp( c, "f" ))
|
||||
{
|
||||
|
@ -1907,13 +2012,19 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
|||
Netchan_OutOfBandPrint( NS_CLIENT, servadr, "info %i", PROTOCOL_VERSION );
|
||||
}
|
||||
}
|
||||
|
||||
if( cls.internetservers_pending )
|
||||
{
|
||||
Cbuf_AddText( "menu_resetping\n" ); // TODO: New Menu API
|
||||
cls.internetservers_pending = false;
|
||||
}
|
||||
}
|
||||
else if( clgame.dllFuncs.pfnConnectionlessPacket( &from, args, buf, &len ))
|
||||
{
|
||||
// user out of band message (must be handled in CL_ConnectionlessPacket)
|
||||
if( len > 0 ) Netchan_OutOfBand( NS_SERVER, from, len, buf );
|
||||
}
|
||||
else MsgDev( D_ERROR, "bad connectionless packet from %s:\n%s\n", NET_AdrToString( from ), args );
|
||||
else Con_DPrintf( S_ERROR "bad connectionless packet from %s:\n%s\n", NET_AdrToString( from ), args );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1948,6 +2059,11 @@ void CL_ReadNetMessage( void )
|
|||
|
||||
while( CL_GetMessage( net_message_buffer, &curSize ))
|
||||
{
|
||||
if( cls.legacymode && *((int *)&net_message_buffer) == 0xFFFFFFFE )
|
||||
// Will rewrite existing packet by merged
|
||||
if( !NetSplit_GetLong( &cls.netchan.netsplit, &net_from, net_message_buffer, &curSize ) )
|
||||
continue;
|
||||
|
||||
MSG_Init( &net_message, "ServerData", net_message_buffer, curSize );
|
||||
|
||||
// check for connectionless packet (0xffffffff) first
|
||||
|
@ -1962,21 +2078,25 @@ void CL_ReadNetMessage( void )
|
|||
|
||||
if( !cls.demoplayback && MSG_GetMaxBytes( &net_message ) < 8 )
|
||||
{
|
||||
MsgDev( D_WARN, "%s: runt packet\n", NET_AdrToString( net_from ));
|
||||
Con_Printf( S_WARN "CL_ReadPackets: %s:runt packet\n", NET_AdrToString( net_from ));
|
||||
continue;
|
||||
}
|
||||
|
||||
// packet from server
|
||||
if( !cls.demoplayback && !NET_CompareAdr( net_from, cls.netchan.remote_address ))
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_ReadPackets: %s:sequenced packet without connection\n", NET_AdrToString( net_from ));
|
||||
Con_DPrintf( S_ERROR "CL_ReadPackets: %s:sequenced packet without connection\n", NET_AdrToString( net_from ));
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !cls.demoplayback && !Netchan_Process( &cls.netchan, &net_message ))
|
||||
continue; // wasn't accepted for some reason
|
||||
|
||||
CL_ParseServerMessage( &net_message, true );
|
||||
// run special handler for quake demos
|
||||
if( cls.demoplayback == DEMO_QUAKE1 )
|
||||
CL_ParseQuakeMessage( &net_message, true );
|
||||
else if( cls.legacymode ) CL_ParseLegacyServerMessage( &net_message, true );
|
||||
else CL_ParseServerMessage( &net_message, true );
|
||||
cl.send_reply = true;
|
||||
}
|
||||
|
||||
|
@ -2019,7 +2139,7 @@ void CL_ReadPackets( void )
|
|||
// decide the simulation time
|
||||
cl.oldtime = cl.time;
|
||||
|
||||
if( !cls.demoplayback && !cl.paused )
|
||||
if( cls.demoplayback != DEMO_XASH3D && !cl.paused )
|
||||
cl.time += host.frametime;
|
||||
|
||||
// demo time
|
||||
|
@ -2034,13 +2154,11 @@ void CL_ReadPackets( void )
|
|||
if( cl.maxclients > 1 && cls.state == ca_active && !host_developer.value )
|
||||
Cvar_SetCheatState();
|
||||
#endif
|
||||
// singleplayer never has connection timeout
|
||||
if( NET_IsLocalAddress( cls.netchan.remote_address ))
|
||||
return;
|
||||
|
||||
// hot precache and downloading resources
|
||||
if( cls.signon == SIGNONS && cl.lastresourcecheck < host.realtime )
|
||||
{
|
||||
double checktime = Host_IsLocalGame() ? 0.1 : 1.0;
|
||||
|
||||
if( !cls.dl.custom && cl.resourcesneeded.pNext != &cl.resourcesneeded )
|
||||
{
|
||||
// check resource for downloading and precache
|
||||
|
@ -2048,9 +2166,14 @@ void CL_ReadPackets( void )
|
|||
CL_BatchResourceRequest( false );
|
||||
cls.dl.custom = true;
|
||||
}
|
||||
cl.lastresourcecheck = host.realtime + 5.0f; // don't checking too often
|
||||
|
||||
cl.lastresourcecheck = host.realtime + checktime;
|
||||
}
|
||||
|
||||
// singleplayer never has connection timeout
|
||||
if( NET_IsLocalAddress( cls.netchan.remote_address ))
|
||||
return;
|
||||
|
||||
// if in the debugger last frame, don't timeout
|
||||
if( host.frametime > 5.0f ) cls.netchan.last_received = Sys_DoubleTime();
|
||||
|
||||
|
@ -2359,7 +2482,7 @@ qboolean CL_PrecacheResources( void )
|
|||
|
||||
if( cl.models[pRes->nIndex] == NULL )
|
||||
{
|
||||
MsgDev( D_ERROR, "submodel %s not found\n", pRes->szFileName );
|
||||
Con_Printf( S_ERROR "submodel %s not found\n", pRes->szFileName );
|
||||
|
||||
if( FBitSet( pRes->ucFlags, RES_FATALIFMISSING ))
|
||||
{
|
||||
|
@ -2386,6 +2509,7 @@ qboolean CL_PrecacheResources( void )
|
|||
{
|
||||
if( FBitSet( pRes->ucFlags, RES_WASMISSING ))
|
||||
{
|
||||
Con_Printf( S_ERROR "%s%s couldn't load\n", DEFAULT_SOUNDPATH, pRes->szFileName );
|
||||
cl.sound_precache[pRes->nIndex][0] = 0;
|
||||
cl.sound_index[pRes->nIndex] = 0;
|
||||
}
|
||||
|
@ -2450,7 +2574,6 @@ qboolean CL_PrecacheResources( void )
|
|||
CL_SetEventIndex( cl.event_precache[pRes->nIndex], pRes->nIndex );
|
||||
break;
|
||||
default:
|
||||
MsgDev( D_REPORT, "unknown resource type\n" );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2558,9 +2681,13 @@ void CL_InitLocal( void )
|
|||
Cvar_Get( "team", "", FCVAR_USERINFO, "player team" );
|
||||
Cvar_Get( "skin", "", FCVAR_USERINFO, "player skin" );
|
||||
|
||||
// legacy mode cvars (need this to add it to userinfo)
|
||||
Cvar_Get( "cl_maxpacket", "0", 0, "legacy server compatibility" );
|
||||
Cvar_Get( "cl_maxpayload", "1000", 0, "legacy server compatibility" );
|
||||
|
||||
cl_showfps = Cvar_Get( "cl_showfps", "1", FCVAR_ARCHIVE, "show client fps" );
|
||||
cl_nosmooth = Cvar_Get( "cl_nosmooth", "0", FCVAR_ARCHIVE, "disable smooth up stair climbing and interpolate position in multiplayer" );
|
||||
cl_smoothtime = Cvar_Get( "cl_smoothtime", "0.1", FCVAR_ARCHIVE, "time to smooth up" );
|
||||
cl_smoothtime = Cvar_Get( "cl_smoothtime", "0", FCVAR_ARCHIVE, "time to smooth up" );
|
||||
cl_cmdbackup = Cvar_Get( "cl_cmdbackup", "10", FCVAR_ARCHIVE, "how many additional history commands are sent" );
|
||||
cl_cmdrate = Cvar_Get( "cl_cmdrate", "30", FCVAR_ARCHIVE, "Max number of command packets sent to server per second" );
|
||||
cl_draw_particles = Cvar_Get( "r_drawparticles", "1", FCVAR_CHEAT, "render particles" );
|
||||
|
@ -2574,6 +2701,7 @@ void CL_InitLocal( void )
|
|||
hud_scale = Cvar_Get( "hud_scale", "0", FCVAR_ARCHIVE|FCVAR_LATCH, "scale hud at current resolution" );
|
||||
Cvar_Get( "cl_background", "0", FCVAR_READ_ONLY, "indicate what background map is running" );
|
||||
cl_showevents = Cvar_Get( "cl_showevents", "0", FCVAR_ARCHIVE, "show events playback" );
|
||||
Cvar_Get( "lastdemo", "", FCVAR_ARCHIVE, "last played demo" );
|
||||
|
||||
// these two added to shut up CS 1.5 about 'unknown' commands
|
||||
Cvar_Get( "lightgamma", "1", FCVAR_ARCHIVE, "ambient lighting level (legacy, unused)" );
|
||||
|
@ -2605,7 +2733,7 @@ void CL_InitLocal( void )
|
|||
Cmd_AddCommand ("record", CL_Record_f, "record a demo" );
|
||||
Cmd_AddCommand ("playdemo", CL_PlayDemo_f, "play a demo" );
|
||||
Cmd_AddCommand ("timedemo", CL_TimeDemo_f, "demo benchmark" );
|
||||
Cmd_AddCommand ("killdemo", CL_DeleteDemo_f, "delete a specified demo file and demoshot" );
|
||||
Cmd_AddCommand ("killdemo", CL_DeleteDemo_f, "delete a specified demo file" );
|
||||
Cmd_AddCommand ("startdemos", CL_StartDemos_f, "start playing back the selected demos sequentially" );
|
||||
Cmd_AddCommand ("demos", CL_Demos_f, "restart looping demos defined by the last startdemos command" );
|
||||
Cmd_AddCommand ("movie", CL_PlayVideo_f, "play a movie" );
|
||||
|
@ -2627,12 +2755,13 @@ void CL_InitLocal( void )
|
|||
Cmd_AddCommand ("skyshot", CL_SkyShot_f, "takes a six-sides envmap (skybox) shot with specified name" );
|
||||
Cmd_AddCommand ("levelshot", CL_LevelShot_f, "same as \"screenshot\", used for create plaque images" );
|
||||
Cmd_AddCommand ("saveshot", CL_SaveShot_f, "used for create save previews with LoadGame menu" );
|
||||
Cmd_AddCommand ("demoshot", CL_DemoShot_f, "used for create demo previews with PlayDemo menu" );
|
||||
|
||||
Cmd_AddCommand ("connect", CL_Connect_f, "connect to a server by hostname" );
|
||||
Cmd_AddCommand ("reconnect", CL_Reconnect_f, "reconnect to current level" );
|
||||
|
||||
Cmd_AddCommand ("rcon", CL_Rcon_f, "sends a command to the server console (rcon_password and rcon_address required)" );
|
||||
Cmd_AddCommand ("precache", CL_LegacyPrecache_f, "legacy server compatibility" );
|
||||
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -2753,12 +2882,6 @@ void Host_ClientFrame( void )
|
|||
// update audio
|
||||
SND_UpdateSound ();
|
||||
|
||||
// animate lightestyles
|
||||
CL_RunLightStyles ();
|
||||
|
||||
// decay dynamic lights
|
||||
CL_DecayLights ();
|
||||
|
||||
// play avi-files
|
||||
SCR_RunCinematic ();
|
||||
|
||||
|
@ -2787,6 +2910,7 @@ void CL_Init( void )
|
|||
MSG_Init( &cls.datagram, "cls.datagram", cls.datagram_buf, sizeof( cls.datagram_buf ));
|
||||
|
||||
IN_TouchInit();
|
||||
Con_LoadHistory();
|
||||
|
||||
if( !CL_LoadProgs( va( "%s/%s", GI->dll_path, SI.clientlib)))
|
||||
Host_Error( "can't initialize %s: %s\n", SI.clientlib, COM_GetLibraryError() );
|
||||
|
|
|
@ -21,10 +21,7 @@ GNU General Public License for more details.
|
|||
#include "library.h"
|
||||
#include "gl_local.h"
|
||||
#include "input.h"
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include "platform/android/android-main.h"
|
||||
#endif
|
||||
#include "platform/platform.h"
|
||||
|
||||
mobile_engfuncs_t *gMobileEngfuncs;
|
||||
|
||||
|
@ -38,23 +35,21 @@ static void pfnVibrate( float life, char flags )
|
|||
|
||||
if( life < 0.0f )
|
||||
{
|
||||
MsgDev( D_WARN, "Negative vibrate time: %f\n", life );
|
||||
Con_Reportf( S_WARN "Negative vibrate time: %f\n", life );
|
||||
return;
|
||||
}
|
||||
|
||||
//MsgDev( D_NOTE, "Vibrate: %f %d\n", life, flags );
|
||||
//Con_Reportf( "Vibrate: %f %d\n", life, flags );
|
||||
|
||||
// here goes platform-specific backends
|
||||
#ifdef __ANDROID__
|
||||
Android_Vibrate( life * vibration_length->value, flags );
|
||||
#endif
|
||||
Platform_Vibrate( life * vibration_length->value, flags );
|
||||
}
|
||||
|
||||
static void Vibrate_f()
|
||||
{
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
Msg( "Usage: vibrate <time>\n" );
|
||||
Msg( S_USAGE "vibrate <time>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -97,13 +92,8 @@ static void *pfnGetNativeObject( const char *obj )
|
|||
if( !obj )
|
||||
return NULL;
|
||||
|
||||
// Backend should handle NULL
|
||||
// Backend should consider that obj is case-sensitive
|
||||
#ifdef __ANDROID__
|
||||
return Android_GetNativeObject( obj );
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
return Platform_GetNativeObject( obj );
|
||||
}
|
||||
|
||||
static mobile_engfuncs_t gpMobileEngfuncs =
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -48,17 +48,10 @@ CL_PushPMStates
|
|||
*/
|
||||
void CL_PushPMStates( void )
|
||||
{
|
||||
if( clgame.pushed )
|
||||
{
|
||||
MsgDev( D_ERROR, "PushPMStates: stack overflow\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if( clgame.pushed ) return;
|
||||
clgame.oldphyscount = clgame.pmove->numphysent;
|
||||
clgame.oldviscount = clgame.pmove->numvisent;
|
||||
clgame.pushed = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -69,16 +62,35 @@ CL_PopPMStates
|
|||
*/
|
||||
void CL_PopPMStates( void )
|
||||
{
|
||||
if( clgame.pushed )
|
||||
{
|
||||
if( !clgame.pushed ) return;
|
||||
clgame.pmove->numphysent = clgame.oldphyscount;
|
||||
clgame.pmove->numvisent = clgame.oldviscount;
|
||||
clgame.pushed = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
MsgDev( D_ERROR, "PopPMStates: stack underflow\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CL_PushTraceBounds
|
||||
|
||||
=============
|
||||
*/
|
||||
void CL_PushTraceBounds( int hullnum, const float *mins, const float *maxs )
|
||||
{
|
||||
hullnum = bound( 0, hullnum, 3 );
|
||||
VectorCopy( mins, clgame.pmove->player_mins[hullnum] );
|
||||
VectorCopy( maxs, clgame.pmove->player_maxs[hullnum] );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CL_PopTraceBounds
|
||||
|
||||
=============
|
||||
*/
|
||||
void CL_PopTraceBounds( void )
|
||||
{
|
||||
memcpy( clgame.pmove->player_mins, host.player_mins, sizeof( host.player_mins ));
|
||||
memcpy( clgame.pmove->player_maxs, host.player_maxs, sizeof( host.player_maxs ));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -90,6 +102,10 @@ qboolean CL_IsPredicted( void )
|
|||
{
|
||||
if( cl_nopred->value || cl.intermission )
|
||||
return false;
|
||||
|
||||
// never predict the quake demos
|
||||
if( cls.demoplayback == DEMO_QUAKE1 )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -456,9 +472,6 @@ void CL_AddLinksToPmove( frame_t *frame )
|
|||
if( VectorIsNull( state->mins ) && VectorIsNull( state->maxs ))
|
||||
continue;
|
||||
|
||||
if ( !model->hulls[1].lastclipnode && model->type != mod_studio )
|
||||
continue;
|
||||
|
||||
if( state->solid == SOLID_NOT && state->skin < CONTENTS_EMPTY )
|
||||
{
|
||||
if( clgame.pmove->nummoveent >= MAX_MOVEENTS )
|
||||
|
@ -470,6 +483,9 @@ void CL_AddLinksToPmove( frame_t *frame )
|
|||
}
|
||||
else
|
||||
{
|
||||
if( !model->hulls[1].lastclipnode && model->type != mod_studio )
|
||||
continue;
|
||||
|
||||
// reserve slots for all the clients
|
||||
if( clgame.pmove->numphysent >= ( MAX_PHYSENTS - cl.maxclients ))
|
||||
continue;
|
||||
|
@ -765,10 +781,7 @@ static void pfnStuckTouch( int hitent, pmtrace_t *tr )
|
|||
}
|
||||
|
||||
if( clgame.pmove->numtouch >= MAX_PHYSENTS )
|
||||
{
|
||||
MsgDev( D_ERROR, "PM_StuckTouch: MAX_TOUCHENTS limit exceeded\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
VectorCopy( clgame.pmove->velocity, tr->deltavelocity );
|
||||
tr->ent = hitent;
|
||||
|
@ -966,7 +979,7 @@ void CL_InitClientMove( void )
|
|||
for( i = 0; i < MAX_MAP_HULLS; i++ )
|
||||
{
|
||||
if( clgame.dllFuncs.pfnGetHullBounds( i, host.player_mins[i], host.player_maxs[i] ))
|
||||
MsgDev( D_NOTE, "CL: hull%i, player_mins: %g %g %g, player_maxs: %g %g %g\n", i,
|
||||
Con_Reportf( "CL: hull%i, player_mins: %g %g %g, player_maxs: %g %g %g\n", i,
|
||||
host.player_mins[i][0], host.player_mins[i][1], host.player_mins[i][2],
|
||||
host.player_maxs[i][0], host.player_maxs[i][1], host.player_maxs[i][2] );
|
||||
}
|
||||
|
@ -1226,7 +1239,7 @@ void CL_PredictMovement( qboolean repredicting )
|
|||
if( cls.state != ca_active || cls.spectator )
|
||||
return;
|
||||
|
||||
if( cls.demoplayback && cl.cmd != NULL && !repredicting )
|
||||
if( cls.demoplayback && !repredicting )
|
||||
CL_DemoInterpolateAngles();
|
||||
|
||||
CL_SetUpPlayerPrediction( false, false );
|
||||
|
@ -1315,7 +1328,7 @@ void CL_PredictMovement( qboolean repredicting )
|
|||
cl.local.onground = frame->playerstate[cl.playernum].onground;
|
||||
else cl.local.onground = -1;
|
||||
|
||||
if( !repredicting || !cl_lw->value )
|
||||
if( !repredicting || !CVAR_TO_BOOL( cl_lw ))
|
||||
cl.local.viewmodel = to->client.viewmodel;
|
||||
cl.local.repredicting = false;
|
||||
cl.local.moving = false;
|
||||
|
@ -1345,7 +1358,7 @@ void CL_PredictMovement( qboolean repredicting )
|
|||
|
||||
cl.local.waterlevel = to->client.waterlevel;
|
||||
cl.local.usehull = to->playerstate.usehull;
|
||||
if( !repredicting || !cl_lw->value )
|
||||
if( !repredicting || !CVAR_TO_BOOL( cl_lw ))
|
||||
cl.local.viewmodel = to->client.viewmodel;
|
||||
|
||||
if( FBitSet( to->client.flags, FL_ONGROUND ))
|
||||
|
|
1133
engine/client/cl_qparse.c
Normal file
1133
engine/client/cl_qparse.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -78,7 +78,9 @@ byte *CL_CreateRawTextureFromPixels( texture_t *tx, size_t *size, int topcolor,
|
|||
// fill header
|
||||
if( !pin.name[0] ) Q_strncpy( pin.name, "#raw_remap_image.mdl", sizeof( pin.name ));
|
||||
pin.flags = STUDIO_NF_COLORMAP; // just in case :-)
|
||||
pin.index = (int)(tx + 1); // pointer to pixels
|
||||
//pin.index = (int)(tx + 1); // pointer to pixels
|
||||
// no more pointer-to-int-to-pointer casts
|
||||
Image_SetMDLPointer( (byte*)((texture_t *)tx + 1) );
|
||||
pin.width = tx->width;
|
||||
pin.height = tx->height;
|
||||
|
||||
|
@ -99,10 +101,11 @@ Dupliacte texture with remap pixels
|
|||
*/
|
||||
void CL_DuplicateTexture( mstudiotexture_t *ptexture, int topcolor, int bottomcolor )
|
||||
{
|
||||
gltexture_t *glt;
|
||||
gl_texture_t *glt;
|
||||
texture_t *tx = NULL;
|
||||
char texname[128];
|
||||
int i, size, index;
|
||||
int i, index;
|
||||
size_t size;
|
||||
byte paletteBackup[768];
|
||||
byte *raw, *pal;
|
||||
|
||||
|
@ -126,7 +129,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, NULL ); // do copy
|
||||
ptexture->index = GL_LoadTexture( texname, raw, size, TF_FORCE_COLOR ); // do copy
|
||||
|
||||
// restore original palette
|
||||
memcpy( pal, paletteBackup, 768 );
|
||||
|
@ -141,11 +144,12 @@ Update texture top and bottom colors
|
|||
*/
|
||||
void CL_UpdateStudioTexture( mstudiotexture_t *ptexture, int topcolor, int bottomcolor )
|
||||
{
|
||||
gltexture_t *glt;
|
||||
gl_texture_t *glt;
|
||||
rgbdata_t *pic;
|
||||
texture_t *tx = NULL;
|
||||
char texname[128], name[128], mdlname[128];
|
||||
int i, size, index;
|
||||
int i, index;
|
||||
size_t size;
|
||||
byte paletteBackup[768];
|
||||
byte *raw, *pal;
|
||||
|
||||
|
@ -179,11 +183,11 @@ void CL_UpdateStudioTexture( mstudiotexture_t *ptexture, int topcolor, int botto
|
|||
pic = FS_LoadImage( glt->name, raw, size );
|
||||
if( !pic )
|
||||
{
|
||||
MsgDev( D_ERROR, "Couldn't update texture %s\n", glt->name );
|
||||
Con_DPrintf( S_ERROR "Couldn't update texture %s\n", glt->name );
|
||||
return;
|
||||
}
|
||||
|
||||
index = GL_LoadTextureInternal( glt->name, pic, 0, true );
|
||||
index = GL_UpdateTextureInternal( glt->name, pic, 0 );
|
||||
FS_FreeImage( pic );
|
||||
|
||||
// restore original palette
|
||||
|
@ -213,7 +217,7 @@ void CL_UpdateAliasTexture( unsigned short *texture, int skinnum, int topcolor,
|
|||
|
||||
if( *texture == 0 )
|
||||
{
|
||||
Q_snprintf( texname, sizeof( texname ), "%s:remap%i", RI.currentmodel->name, skinnum );
|
||||
Q_snprintf( texname, sizeof( texname ), "%s:remap%i_%i", RI.currentmodel->name, skinnum, RI.currententity->index );
|
||||
skin.width = tx->width;
|
||||
skin.height = tx->height;
|
||||
skin.depth = skin.numMips = 1;
|
||||
|
@ -224,7 +228,7 @@ void CL_UpdateAliasTexture( unsigned short *texture, int skinnum, int topcolor,
|
|||
skin.buffer = (byte *)(tx + 1);
|
||||
skin.palette = skin.buffer + skin.size;
|
||||
pic = FS_CopyImage( &skin ); // because GL_LoadTextureInternal will freed a rgbdata_t at end
|
||||
*texture = GL_LoadTextureInternal( texname, pic, TF_KEEP_SOURCE, false );
|
||||
*texture = GL_LoadTextureInternal( texname, pic, TF_KEEP_SOURCE );
|
||||
}
|
||||
|
||||
// and now we can remap with internal routines
|
||||
|
@ -288,7 +292,7 @@ void CL_AllocRemapInfo( int topcolor, int bottomcolor )
|
|||
// e.g. playermodel 'barney' with playermodel 'gordon'
|
||||
if( clgame.remap_info[i] ) CL_FreeRemapInfo( clgame.remap_info[i] ); // free old info
|
||||
size = sizeof( remap_info_t ) + ( sizeof( mstudiotexture_t ) * phdr->numtextures );
|
||||
info = clgame.remap_info[i] = Mem_Alloc( clgame.mempool, size );
|
||||
info = clgame.remap_info[i] = Mem_Calloc( clgame.mempool, size );
|
||||
info->ptexture = (mstudiotexture_t *)(info + 1); // textures are immediately comes after remap_info
|
||||
}
|
||||
else
|
||||
|
@ -325,7 +329,7 @@ void CL_AllocRemapInfo( int topcolor, int bottomcolor )
|
|||
// this code catches studiomodel change with another studiomodel with remap textures
|
||||
// e.g. playermodel 'barney' with playermodel 'gordon'
|
||||
if( clgame.remap_info[i] ) CL_FreeRemapInfo( clgame.remap_info[i] ); // free old info
|
||||
info = clgame.remap_info[i] = Mem_Alloc( clgame.mempool, sizeof( remap_info_t ));
|
||||
info = clgame.remap_info[i] = Mem_Calloc( clgame.mempool, sizeof( remap_info_t ));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -176,7 +176,7 @@ SCR_RSpeeds
|
|||
*/
|
||||
void SCR_RSpeeds( void )
|
||||
{
|
||||
char msg[MAX_SYSPATH];
|
||||
char msg[2048];
|
||||
|
||||
if( !host.allow_console )
|
||||
return;
|
||||
|
@ -202,6 +202,9 @@ void SCR_RSpeeds( void )
|
|||
Con_DrawString( x, y, p, color );
|
||||
y += height;
|
||||
|
||||
// handle '\n\n'
|
||||
if( *p == '\n' )
|
||||
y += height;
|
||||
if( end ) p = end + 1;
|
||||
else break;
|
||||
} while( 1 );
|
||||
|
@ -252,7 +255,6 @@ void SCR_MakeScreenShot( void )
|
|||
iRet = VID_ScreenShot( cls.shotname, VID_LEVELSHOT );
|
||||
break;
|
||||
case scrshot_savegame:
|
||||
case scrshot_demoshot:
|
||||
iRet = VID_ScreenShot( cls.shotname, VID_MINISHOT );
|
||||
break;
|
||||
case scrshot_envshot:
|
||||
|
@ -273,9 +275,9 @@ void SCR_MakeScreenShot( void )
|
|||
{
|
||||
// snapshots don't writes message about image
|
||||
if( cls.scrshot_action != scrshot_snapshot )
|
||||
MsgDev( D_REPORT, "Write %s\n", cls.shotname );
|
||||
Con_Reportf( "Write %s\n", cls.shotname );
|
||||
}
|
||||
else MsgDev( D_ERROR, "Unable to write %s\n", cls.shotname );
|
||||
else Con_Printf( S_ERROR "Unable to write %s\n", cls.shotname );
|
||||
|
||||
cls.envshot_vieworg = NULL;
|
||||
cls.scrshot_action = scrshot_inactive;
|
||||
|
@ -293,7 +295,7 @@ 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, NULL );
|
||||
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 );
|
||||
if( !cl.background ) CL_DrawHUD( CL_LOADING );
|
||||
|
@ -408,10 +410,10 @@ void SCR_TileClear( void )
|
|||
if( clear.y2 <= clear.y1 )
|
||||
return; // nothing disturbed
|
||||
|
||||
top = RI.viewport[1];
|
||||
bottom = top + RI.viewport[3] - 1;
|
||||
left = RI.viewport[0];
|
||||
right = left + RI.viewport[2] - 1;
|
||||
top = clgame.viewport[1];
|
||||
bottom = top + clgame.viewport[3] - 1;
|
||||
left = clgame.viewport[0];
|
||||
right = left + clgame.viewport[2] - 1;
|
||||
|
||||
if( clear.y1 < top )
|
||||
{
|
||||
|
@ -493,7 +495,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, NULL );
|
||||
cls.creditsFont.hFontTexture = 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;
|
||||
|
@ -525,7 +527,7 @@ qboolean SCR_LoadVariableWidthFont( const char *fontname )
|
|||
if( !FS_FileExists( fontname, false ))
|
||||
return false;
|
||||
|
||||
cls.creditsFont.hFontTexture = GL_LoadTexture( fontname, NULL, 0, TF_IMAGE, NULL );
|
||||
cls.creditsFont.hFontTexture = GL_LoadTexture( fontname, NULL, 0, TF_IMAGE );
|
||||
R_GetTextureParms( &fontWidth, NULL, cls.creditsFont.hFontTexture );
|
||||
|
||||
// half-life font with variable chars witdh
|
||||
|
@ -577,7 +579,7 @@ void SCR_LoadCreditsFont( void )
|
|||
if( !SCR_LoadVariableWidthFont( path ))
|
||||
{
|
||||
if( !SCR_LoadFixedWidthFont( "gfx/conchars" ))
|
||||
MsgDev( D_ERROR, "failed to load HUD font\n" );
|
||||
Con_DPrintf( S_ERROR "failed to load HUD font\n" );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -594,8 +596,8 @@ void SCR_InstallParticlePalette( void )
|
|||
int i;
|
||||
|
||||
// first check 'palette.lmp' then 'palette.pal'
|
||||
pic = FS_LoadImage( "gfx/palette.lmp", NULL, 0 );
|
||||
if( !pic ) pic = FS_LoadImage( "gfx/palette.pal", NULL, 0 );
|
||||
pic = FS_LoadImage( DEFAULT_INTERNAL_PALETTE, NULL, 0 );
|
||||
if( !pic ) pic = FS_LoadImage( DEFAULT_EXTERNAL_PALETTE, NULL, 0 );
|
||||
|
||||
// NOTE: imagelib required this fakebuffer for loading internal palette
|
||||
if( !pic ) pic = FS_LoadImage( "#valve.pal", (byte *)&i, 768 );
|
||||
|
@ -612,13 +614,13 @@ void SCR_InstallParticlePalette( void )
|
|||
}
|
||||
else
|
||||
{
|
||||
// someone deleted internal palette from code...
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
clgame.palette[i].r = i;
|
||||
clgame.palette[i].g = i;
|
||||
clgame.palette[i].b = i;
|
||||
}
|
||||
MsgDev( D_WARN, "CL_InstallParticlePalette: failed. Force to grayscale\n" );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -634,24 +636,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, NULL );
|
||||
cls.pauseIcon = 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, NULL );
|
||||
cls.pauseIcon = 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, NULL );
|
||||
else cls.loadingBar = GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE, NULL );
|
||||
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 );
|
||||
}
|
||||
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, NULL );
|
||||
else cls.loadingBar = GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE, NULL );
|
||||
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.tileImage = GL_LoadTexture( "gfx/backtile.lmp", NULL, 0, TF_NOMIPMAP, NULL );
|
||||
cls.tileImage = GL_LoadTexture( "gfx/backtile.lmp", NULL, 0, TF_NOMIPMAP );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -718,7 +720,6 @@ void SCR_Init( void )
|
|||
{
|
||||
if( scr_init ) return;
|
||||
|
||||
MsgDev( D_NOTE, "SCR_Init()\n" );
|
||||
scr_centertime = Cvar_Get( "scr_centertime", "2.5", 0, "centerprint hold time" );
|
||||
cl_levelshot_name = Cvar_Get( "cl_levelshot_name", "*black", 0, "contains path to current levelshot" );
|
||||
cl_allow_levelshots = Cvar_Get( "allow_levelshots", "0", FCVAR_ARCHIVE, "allow engine to use indivdual levelshots instead of 'loading' image" );
|
||||
|
@ -732,6 +733,7 @@ void SCR_Init( void )
|
|||
// 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" );
|
||||
Cmd_AddCommand( "sizeup", SCR_SizeUp_f, "screen size up to 10 points" );
|
||||
Cmd_AddCommand( "sizedown", SCR_SizeDown_f, "screen size down to 10 points" );
|
||||
|
@ -742,12 +744,12 @@ void SCR_Init( void )
|
|||
host.allow_console = true; // we need console, because menu is missing
|
||||
}
|
||||
|
||||
SCR_VidInit();
|
||||
SCR_LoadCreditsFont ();
|
||||
SCR_InstallParticlePalette ();
|
||||
SCR_RegisterTextures ();
|
||||
SCR_InstallParticlePalette ();
|
||||
SCR_InitCinematic();
|
||||
CL_InitNetgraph();
|
||||
SCR_VidInit();
|
||||
|
||||
if( host.allow_console && Sys_CheckParm( "-toconsole" ))
|
||||
Cbuf_AddText( "toggleconsole\n" );
|
||||
|
@ -760,7 +762,6 @@ void SCR_Shutdown( void )
|
|||
{
|
||||
if( !scr_init ) return;
|
||||
|
||||
MsgDev( D_NOTE, "SCR_Shutdown()\n" );
|
||||
Cmd_RemoveCommand( "timerefresh" );
|
||||
Cmd_RemoveCommand( "skyname" );
|
||||
Cmd_RemoveCommand( "viewpos" );
|
||||
|
|
|
@ -127,7 +127,7 @@ void CL_AddClientResource( const char *filename, int type )
|
|||
if( p != &cl.resourcesneeded )
|
||||
return; // already in list?
|
||||
|
||||
pResource = Mem_Alloc( cls.mempool, sizeof( resource_t ));
|
||||
pResource = Mem_Calloc( cls.mempool, sizeof( resource_t ));
|
||||
|
||||
Q_strncpy( pResource->szFileName, filename, sizeof( pResource->szFileName ));
|
||||
pResource->type = type;
|
||||
|
@ -151,7 +151,7 @@ void CL_AddClientResources( void )
|
|||
int i;
|
||||
|
||||
// don't request resources from localhost or in quake-compatibility mode
|
||||
if( cl.maxclients <= 1 || FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
if( cl.maxclients <= 1 || Host_IsQuakeCompatible( ))
|
||||
return;
|
||||
|
||||
// check sprites first
|
||||
|
@ -325,7 +325,7 @@ CL_InitTempents
|
|||
*/
|
||||
void CL_InitTempEnts( void )
|
||||
{
|
||||
cl_tempents = Mem_Alloc( cls.mempool, sizeof( TEMPENTITY ) * GI->max_tents );
|
||||
cl_tempents = Mem_Calloc( cls.mempool, sizeof( TEMPENTITY ) * GI->max_tents );
|
||||
CL_ClearTempEnts();
|
||||
|
||||
// load tempent sprites (glowshell, muzzleflashes etc)
|
||||
|
@ -593,7 +593,7 @@ TEMPENTITY *CL_TempEntAlloc( const vec3_t org, model_t *pmodel )
|
|||
|
||||
if( !cl_free_tents )
|
||||
{
|
||||
MsgDev( D_INFO, "Overflow %d temporary ents!\n", GI->max_tents );
|
||||
Con_DPrintf( "Overflow %d temporary ents!\n", GI->max_tents );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -633,7 +633,7 @@ TEMPENTITY *CL_TempEntAllocHigh( const vec3_t org, model_t *pmodel )
|
|||
{
|
||||
// didn't find anything? The tent list is either full of high-priority tents
|
||||
// or all tents in the list are still due to live for > 10 seconds.
|
||||
MsgDev( D_INFO, "Couldn't alloc a high priority TENT!\n" );
|
||||
Con_DPrintf( "Couldn't alloc a high priority TENT!\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -870,10 +870,7 @@ void R_AttachTentToPlayer( int client, int modelIndex, float zoffset, float life
|
|||
model_t *pModel;
|
||||
|
||||
if( client <= 0 || client > cl.maxclients )
|
||||
{
|
||||
MsgDev( D_ERROR, "Bad client %i in AttachTentToPlayer()!\n", client );
|
||||
return;
|
||||
}
|
||||
|
||||
pClient = CL_GetEntityByIndex( client );
|
||||
|
||||
|
@ -926,10 +923,7 @@ void R_KillAttachedTents( int client )
|
|||
int i;
|
||||
|
||||
if( client <= 0 || client > cl.maxclients )
|
||||
{
|
||||
MsgDev( D_ERROR, "Bad client %i in KillAttachedTents()!\n", client );
|
||||
return;
|
||||
}
|
||||
|
||||
for( i = 0; i < GI->max_tents; i++ )
|
||||
{
|
||||
|
@ -1282,7 +1276,7 @@ TEMPENTITY *R_DefaultSprite( const vec3_t pos, int spriteIndex, float framerate
|
|||
|
||||
if(( psprite = CL_ModelHandle( spriteIndex )) == NULL || psprite->type != mod_sprite )
|
||||
{
|
||||
MsgDev( D_INFO, "No Sprite %d!\n", spriteIndex );
|
||||
Con_Reportf( "No Sprite %d!\n", spriteIndex );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1339,7 +1333,7 @@ TEMPENTITY *R_TempSprite( vec3_t pos, const vec3_t dir, float scale, int modelIn
|
|||
|
||||
if(( pmodel = CL_ModelHandle( modelIndex )) == NULL )
|
||||
{
|
||||
MsgDev( D_ERROR, "No model %d!\n", modelIndex );
|
||||
Con_Reportf( S_ERROR "No model %d!\n", modelIndex );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1446,7 +1440,7 @@ void R_Spray( const vec3_t pos, const vec3_t dir, int modelIndex, int count, int
|
|||
|
||||
if(( pmodel = CL_ModelHandle( modelIndex )) == NULL )
|
||||
{
|
||||
MsgDev( D_INFO, "No model %d!\n", modelIndex );
|
||||
Con_Reportf( "No model %d!\n", modelIndex );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1577,7 +1571,7 @@ void R_FunnelSprite( const vec3_t org, int modelIndex, int reverse )
|
|||
|
||||
if(( pmodel = CL_ModelHandle( modelIndex )) == NULL )
|
||||
{
|
||||
MsgDev( D_ERROR, "no model %d!\n", modelIndex );
|
||||
Con_Reportf( S_ERROR "no model %d!\n", modelIndex );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1823,10 +1817,7 @@ void R_PlayerSprites( int client, int modelIndex, int count, int size )
|
|||
pEnt = CL_GetEntityByIndex( client );
|
||||
|
||||
if( !pEnt || !pEnt->player )
|
||||
{
|
||||
MsgDev( D_INFO, "Bad ent %i in R_PlayerSprites()!\n", client );
|
||||
return;
|
||||
}
|
||||
|
||||
vel = 128;
|
||||
|
||||
|
@ -2033,7 +2024,7 @@ void CL_ParseTempEntity( sizebuf_t *msg )
|
|||
{
|
||||
sizebuf_t buf;
|
||||
byte pbuf[256];
|
||||
int iSize = MSG_ReadWord( msg );
|
||||
int iSize;
|
||||
int type, color, count, flags;
|
||||
int decalIndex, modelIndex, entityIndex;
|
||||
float scale, life, frameRate, vel, random;
|
||||
|
@ -2044,6 +2035,10 @@ void CL_ParseTempEntity( sizebuf_t *msg )
|
|||
cl_entity_t *pEnt;
|
||||
dlight_t *dl;
|
||||
|
||||
if( cls.legacymode )
|
||||
iSize = MSG_ReadByte( msg );
|
||||
else iSize = MSG_ReadWord( msg );
|
||||
|
||||
decalIndex = modelIndex = entityIndex = 0;
|
||||
|
||||
// parse user message into buffer
|
||||
|
@ -2511,12 +2506,13 @@ void CL_ParseTempEntity( sizebuf_t *msg )
|
|||
R_UserTracerParticle( pos, pos2, life, color, scale, 0, NULL );
|
||||
break;
|
||||
default:
|
||||
MsgDev( D_ERROR, "ParseTempEntity: illegible TE message %i\n", type );
|
||||
Con_DPrintf( S_ERROR "ParseTempEntity: illegible TE message %i\n", type );
|
||||
break;
|
||||
}
|
||||
|
||||
// throw warning
|
||||
if( MSG_CheckOverflow( &buf )) MsgDev( D_WARN, "ParseTempEntity: overflow TE message\n" );
|
||||
if( MSG_CheckOverflow( &buf ))
|
||||
Con_DPrintf( S_WARN "ParseTempEntity: overflow TE message\n" );
|
||||
}
|
||||
|
||||
|
||||
|
@ -2573,7 +2569,8 @@ void CL_SetLightstyle( int style, const char *s, float f )
|
|||
break;
|
||||
}
|
||||
}
|
||||
MsgDev( D_REPORT, "Lightstyle %i (%s), interp %s\n", style, ls->pattern, ls->interp ? "Yes" : "No" );
|
||||
|
||||
Con_Reportf( "Lightstyle %i (%s), interp %s\n", style, ls->pattern, ls->interp ? "Yes" : "No" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2808,7 +2805,7 @@ void CL_AddEntityEffects( cl_entity_t *ent )
|
|||
|
||||
if( FBitSet( ent->curstate.effects, EF_DIMLIGHT ))
|
||||
{
|
||||
if( ent->player && !FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
if( ent->player && !Host_IsQuakeCompatible( ))
|
||||
{
|
||||
CL_UpdateFlashlight( ent );
|
||||
}
|
||||
|
@ -2845,7 +2842,7 @@ void CL_AddEntityEffects( cl_entity_t *ent )
|
|||
}
|
||||
|
||||
// studio models are handle muzzleflashes difference
|
||||
if( FBitSet( ent->curstate.effects, EF_MUZZLEFLASH ) && ent->model->type == mod_alias )
|
||||
if( FBitSet( ent->curstate.effects, EF_MUZZLEFLASH ) && Mod_AliasExtradata( ent->model ))
|
||||
{
|
||||
dlight_t *dl = CL_AllocDlight( ent->index );
|
||||
vec3_t fv;
|
||||
|
@ -2871,6 +2868,7 @@ these effects will be enable by flag in model header
|
|||
*/
|
||||
void CL_AddModelEffects( cl_entity_t *ent )
|
||||
{
|
||||
vec3_t neworigin;
|
||||
vec3_t oldorigin;
|
||||
|
||||
if( !ent->model ) return;
|
||||
|
@ -2883,23 +2881,33 @@ void CL_AddModelEffects( cl_entity_t *ent )
|
|||
default: return;
|
||||
}
|
||||
|
||||
if( cls.demoplayback == DEMO_QUAKE1 )
|
||||
{
|
||||
VectorCopy( ent->baseline.vuser1, oldorigin );
|
||||
VectorCopy( ent->origin, ent->baseline.vuser1 );
|
||||
VectorCopy( ent->origin, neworigin );
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy( ent->prevstate.origin, oldorigin );
|
||||
VectorCopy( ent->curstate.origin, neworigin );
|
||||
}
|
||||
|
||||
// NOTE: this completely over control about angles and don't broke interpolation
|
||||
if( FBitSet( ent->model->flags, STUDIO_ROTATE ))
|
||||
ent->angles[1] = anglemod( 100.0f * cl.time );
|
||||
|
||||
if( FBitSet( ent->model->flags, STUDIO_GIB ))
|
||||
R_RocketTrail( oldorigin, ent->curstate.origin, 2 );
|
||||
R_RocketTrail( oldorigin, neworigin, 2 );
|
||||
|
||||
if( FBitSet( ent->model->flags, STUDIO_ZOMGIB ))
|
||||
R_RocketTrail( oldorigin, ent->curstate.origin, 4 );
|
||||
R_RocketTrail( oldorigin, neworigin, 4 );
|
||||
|
||||
if( FBitSet( ent->model->flags, STUDIO_TRACER ))
|
||||
R_RocketTrail( oldorigin, ent->curstate.origin, 3 );
|
||||
R_RocketTrail( oldorigin, neworigin, 3 );
|
||||
|
||||
if( FBitSet( ent->model->flags, STUDIO_TRACER2 ))
|
||||
R_RocketTrail( oldorigin, ent->curstate.origin, 5 );
|
||||
R_RocketTrail( oldorigin, neworigin, 5 );
|
||||
|
||||
if( FBitSet( ent->model->flags, STUDIO_ROCKET ))
|
||||
{
|
||||
|
@ -2915,14 +2923,14 @@ void CL_AddModelEffects( cl_entity_t *ent )
|
|||
|
||||
dl->die = cl.time + 0.01f;
|
||||
|
||||
R_RocketTrail( oldorigin, ent->curstate.origin, 0 );
|
||||
R_RocketTrail( oldorigin, neworigin, 0 );
|
||||
}
|
||||
|
||||
if( FBitSet( ent->model->flags, STUDIO_GRENADE ))
|
||||
R_RocketTrail( oldorigin, ent->curstate.origin, 1 );
|
||||
R_RocketTrail( oldorigin, neworigin, 1 );
|
||||
|
||||
if( FBitSet( ent->model->flags, STUDIO_TRACER3 ))
|
||||
R_RocketTrail( oldorigin, ent->curstate.origin, 6 );
|
||||
R_RocketTrail( oldorigin, neworigin, 6 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3014,7 +3022,7 @@ void CL_PlayerDecal( int playernum, int customIndex, int entityIndex, float *pos
|
|||
if( !pCust->nUserData1 && pCust->pInfo != NULL )
|
||||
{
|
||||
const char *decalname = va( "player%dlogo%d", playernum, customIndex );
|
||||
pCust->nUserData1 = GL_LoadTextureInternal( decalname, pCust->pInfo, TF_DECAL, false );
|
||||
pCust->nUserData1 = GL_LoadTextureInternal( decalname, pCust->pInfo, TF_DECAL );
|
||||
}
|
||||
textureIndex = pCust->nUserData1;
|
||||
}
|
||||
|
@ -3060,7 +3068,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, NULL );
|
||||
cl.decal_index[id] = GL_LoadTexture( host.draw_decals[id], NULL, 0, TF_DECAL );
|
||||
Image_ClearForceFlags();
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ qboolean SCR_NextMovie( void )
|
|||
{
|
||||
S_StopAllSounds( true );
|
||||
SCR_StopCinematic();
|
||||
CL_CheckStartupDemos();
|
||||
return false; // don't play movies
|
||||
}
|
||||
|
||||
|
@ -56,6 +57,7 @@ qboolean SCR_NextMovie( void )
|
|||
S_StopAllSounds( true );
|
||||
SCR_StopCinematic();
|
||||
cls.movienum = -1;
|
||||
CL_CheckStartupDemos();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -90,6 +92,7 @@ void SCR_CheckStartupVids( void )
|
|||
{
|
||||
// don't run movies where we in developer-mode
|
||||
cls.movienum = -1;
|
||||
CL_CheckStartupDemos();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -206,7 +209,7 @@ qboolean SCR_PlayCinematic( const char *arg )
|
|||
|
||||
if( FS_FileExists( arg, false ) && !fullpath )
|
||||
{
|
||||
MsgDev( D_ERROR, "Couldn't load %s from packfile. Please extract it\n", path );
|
||||
Con_Printf( S_ERROR "Couldn't load %s from packfile. Please extract it\n", path );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -232,13 +235,14 @@ qboolean SCR_PlayCinematic( const char *arg )
|
|||
|
||||
UI_SetActiveMenu( false );
|
||||
cls.state = ca_cinematic;
|
||||
Con_FastClose();
|
||||
cin_time = 0.0f;
|
||||
cls.signon = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
long SCR_GetAudioChunk( char *rawdata, long length )
|
||||
int SCR_GetAudioChunk( char *rawdata, int length )
|
||||
{
|
||||
int r;
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ GNU General Public License for more details.
|
|||
#include "entity_types.h"
|
||||
#include "gl_local.h"
|
||||
#include "vgui_draw.h"
|
||||
#include "sound.h"
|
||||
|
||||
/*
|
||||
===============
|
||||
|
@ -143,7 +144,7 @@ void V_SetRefParams( ref_params_t *fd )
|
|||
fd->demoplayback = cls.demoplayback;
|
||||
fd->hardware = 1; // OpenGL
|
||||
|
||||
if( cl.first_frame )
|
||||
if( cl.first_frame || cl.skip_interp )
|
||||
{
|
||||
cl.first_frame = false; // now can be unlocked
|
||||
fd->smoothing = true; // NOTE: currently this used to prevent ugly un-duck effect while level is changed
|
||||
|
@ -286,7 +287,7 @@ qboolean V_PreRender( void )
|
|||
{
|
||||
if(( host.realtime - cls.disable_screen ) > cl_timeout->value )
|
||||
{
|
||||
MsgDev( D_ERROR, "V_PreRender: loading plaque timed out\n" );
|
||||
Con_Reportf( "V_PreRender: loading plaque timed out\n" );
|
||||
cls.disable_screen = 0.0f;
|
||||
}
|
||||
return false;
|
||||
|
@ -334,6 +335,7 @@ void V_RenderView( void )
|
|||
}
|
||||
|
||||
R_RenderFrame( &rvp );
|
||||
S_UpdateFrame( &rvp );
|
||||
viewnum++;
|
||||
|
||||
} while( rp.nextView );
|
||||
|
@ -382,6 +384,7 @@ void V_PostRender( void )
|
|||
CL_DrawDemoRecording();
|
||||
CL_DrawHUD( CL_CHANGELEVEL );
|
||||
R_ShowTextures();
|
||||
R_ShowTree();
|
||||
Con_DrawConsole();
|
||||
UI_UpdateMenu( host.realtime );
|
||||
Con_DrawVersion();
|
||||
|
|
|
@ -53,6 +53,13 @@ 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
|
||||
{
|
||||
|
@ -214,6 +221,7 @@ typedef struct
|
|||
qboolean background; // not real game, just a background
|
||||
qboolean first_frame; // first rendering frame
|
||||
qboolean proxy_redirect; // spectator stuff
|
||||
qboolean skip_interp; // skip interpolation this frame
|
||||
|
||||
uint checksum; // for catching cheater maps
|
||||
|
||||
|
@ -312,7 +320,6 @@ typedef enum
|
|||
scrshot_snapshot, // in-game snapshot
|
||||
scrshot_plaque, // levelshot
|
||||
scrshot_savegame, // saveshot
|
||||
scrshot_demoshot, // for demos preview
|
||||
scrshot_envshot, // cubemap view
|
||||
scrshot_skyshot, // skybox view
|
||||
scrshot_mapshot // overview layer
|
||||
|
@ -541,8 +548,8 @@ typedef struct
|
|||
ui_globalvars_t *globals;
|
||||
|
||||
qboolean drawLogo; // set to TRUE if logo.avi missed or corrupted
|
||||
long logo_xres;
|
||||
long logo_yres;
|
||||
int logo_xres;
|
||||
int logo_yres;
|
||||
float logo_length;
|
||||
|
||||
qboolean use_text_api;
|
||||
|
@ -595,6 +602,7 @@ typedef struct
|
|||
|
||||
float packet_loss;
|
||||
double packet_loss_recalc_time;
|
||||
int starting_count; // message num readed bits
|
||||
|
||||
float nextcmdtime; // when can we send the next command packet?
|
||||
int lastoutgoingcommand; // sequence number of last outgoing command
|
||||
|
@ -603,6 +611,7 @@ typedef struct
|
|||
int td_lastframe; // to meter out one message a frame
|
||||
int td_startframe; // host_framecount at start
|
||||
double td_starttime; // realtime at second frame of timedemo
|
||||
int forcetrack; // -1 = use normal cd track
|
||||
|
||||
// game images
|
||||
int pauseIcon; // draw 'paused' when game in-pause
|
||||
|
@ -632,7 +641,8 @@ typedef struct
|
|||
// demo loop control
|
||||
int demonum; // -1 = don't play demos
|
||||
int olddemonum; // restore playing
|
||||
string demos[MAX_DEMOS]; // when not playing
|
||||
char demos[MAX_DEMOS][MAX_QPATH]; // when not playing
|
||||
qboolean demos_pending;
|
||||
|
||||
// movie playlist
|
||||
int movienum;
|
||||
|
@ -645,9 +655,14 @@ typedef struct
|
|||
qboolean timedemo;
|
||||
string demoname; // for demo looping
|
||||
double demotime; // recording time
|
||||
qboolean set_lastdemo; // store name of last played demo into the cvar
|
||||
|
||||
file_t *demofile;
|
||||
file_t *demoheader; // contain demo startup info in case we record a demo on this level
|
||||
qboolean internetservers_wait; // internetservers is waiting for dns request
|
||||
qboolean internetservers_pending; // internetservers is waiting for dns request
|
||||
qboolean legacymode; // one-way 48 protocol compatibility
|
||||
netadr_t legacyserver;
|
||||
} client_static_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -730,7 +745,6 @@ void CL_PlayCDTrack_f( void );
|
|||
void CL_EnvShot_f( void );
|
||||
void CL_SkyShot_f( void );
|
||||
void CL_SaveShot_f( void );
|
||||
void CL_DemoShot_f( void );
|
||||
void CL_LevelShot_f( void );
|
||||
void CL_SetSky_f( void );
|
||||
void SCR_Viewpos_f( void );
|
||||
|
@ -745,6 +759,15 @@ void CL_RemoveFromResourceList( resource_t *pResource );
|
|||
void CL_MoveToOnHandList( resource_t *pResource );
|
||||
void CL_ClearResourceLists( void );
|
||||
|
||||
//
|
||||
// cl_debug.c
|
||||
//
|
||||
void CL_Parse_Debug( qboolean enable );
|
||||
void CL_Parse_RecordCommand( int cmd, int startoffset );
|
||||
void CL_ResetFrame( frame_t *frame );
|
||||
void CL_WriteMessageHistory( void );
|
||||
const char *CL_MsgInfo( int cmd );
|
||||
|
||||
//
|
||||
// cl_main.c
|
||||
//
|
||||
|
@ -772,8 +795,10 @@ void CL_WriteDemoMessage( qboolean startup, int start, sizebuf_t *msg );
|
|||
void CL_WriteDemoUserMessage( const byte *buffer, size_t size );
|
||||
qboolean CL_DemoReadMessage( byte *buffer, size_t *length );
|
||||
void CL_DemoInterpolateAngles( void );
|
||||
void CL_CheckStartupDemos( void );
|
||||
void CL_WriteDemoJumpTime( void );
|
||||
void CL_CloseDemoHeader( void );
|
||||
void CL_DemoCompleted( void );
|
||||
void CL_StopPlayback( void );
|
||||
void CL_StopRecord( void );
|
||||
void CL_PlayDemo_f( void );
|
||||
|
@ -783,7 +808,6 @@ void CL_Demos_f( void );
|
|||
void CL_DeleteDemo_f( void );
|
||||
void CL_Record_f( void );
|
||||
void CL_Stop_f( void );
|
||||
void CL_FreeDemo( void );
|
||||
|
||||
//
|
||||
// cl_events.c
|
||||
|
@ -851,11 +875,16 @@ _inline cl_entity_t *CL_EDICT_NUM( int n )
|
|||
// cl_parse.c
|
||||
//
|
||||
void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message );
|
||||
void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message );
|
||||
void CL_LegacyPrecache_f( void );
|
||||
|
||||
void CL_ParseTempEntity( sizebuf_t *msg );
|
||||
void CL_StartResourceDownloading( const char *pszMessage, qboolean bCustom );
|
||||
qboolean CL_DispatchUserMessage( const char *pszName, int iSize, void *pbuf );
|
||||
qboolean CL_RequestMissingResources( void );
|
||||
void CL_RegisterResources ( sizebuf_t *msg );
|
||||
void CL_ParseViewEntity( sizebuf_t *msg );
|
||||
void CL_ParseServerTime( sizebuf_t *msg );
|
||||
|
||||
//
|
||||
// cl_scrn.c
|
||||
|
@ -907,6 +936,8 @@ void CL_SetupPMove( playermove_t *pmove, local_state_t *from, usercmd_t *ucmd, q
|
|||
int CL_TestLine( const vec3_t start, const vec3_t end, int flags );
|
||||
pmtrace_t *CL_VisTraceLine( vec3_t start, vec3_t end, int flags );
|
||||
pmtrace_t CL_TraceLine( vec3_t start, vec3_t end, int flags );
|
||||
void CL_PushTraceBounds( int hullnum, const float *mins, const float *maxs );
|
||||
void CL_PopTraceBounds( void );
|
||||
void CL_MoveSpectatorCamera( void );
|
||||
void CL_SetLastUpdate( void );
|
||||
void CL_RedoPrediction( void );
|
||||
|
@ -915,6 +946,11 @@ void CL_PushPMStates( void );
|
|||
void CL_PopPMStates( void );
|
||||
void CL_SetUpPlayerPrediction( int dopred, int bIncludeLocalClient );
|
||||
|
||||
//
|
||||
// cl_qparse.c
|
||||
//
|
||||
void CL_ParseQuakeMessage( sizebuf_t *msg, qboolean normal_message );
|
||||
|
||||
//
|
||||
// cl_studio.c
|
||||
//
|
||||
|
@ -923,15 +959,16 @@ void CL_InitStudioAPI( void );
|
|||
//
|
||||
// cl_frame.c
|
||||
//
|
||||
typedef struct channel_s channel_t;
|
||||
typedef struct rawchan_s rawchan_t;
|
||||
struct channel_s;
|
||||
struct rawchan_s;
|
||||
int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta );
|
||||
qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType );
|
||||
void CL_ResetLatchedVars( cl_entity_t *ent, qboolean full_reset );
|
||||
qboolean CL_GetEntitySpatialization( channel_t *ch );
|
||||
qboolean CL_GetMovieSpatialization( rawchan_t *ch );
|
||||
qboolean CL_GetEntitySpatialization( struct channel_s *ch );
|
||||
qboolean CL_GetMovieSpatialization( struct rawchan_s *ch );
|
||||
void CL_ProcessPlayerState( int playerindex, entity_state_t *state );
|
||||
void CL_ComputePlayerOrigin( cl_entity_t *clent );
|
||||
void CL_UpdateEntityFields( cl_entity_t *ent );
|
||||
void CL_ProcessPacket( frame_t *frame );
|
||||
void CL_MoveThirdpersonCamera( void );
|
||||
qboolean CL_IsPlayerIndex( int idx );
|
||||
void CL_SetIdealPitch( void );
|
||||
|
@ -950,7 +987,7 @@ void CL_ClearAllRemaps( void );
|
|||
//
|
||||
// cl_tent.c
|
||||
//
|
||||
typedef struct particle_s particle_t;
|
||||
struct particle_s;
|
||||
int CL_AddEntity( int entityType, cl_entity_t *pEnt );
|
||||
void CL_WeaponAnim( int iAnim, int body );
|
||||
void CL_ClearEffects( void );
|
||||
|
@ -960,7 +997,7 @@ void CL_DrawParticlesExternal( const ref_viewpass_t *rvp, qboolean trans_pass, f
|
|||
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 );
|
||||
void R_FreeDeadParticles( particle_t **ppparticles );
|
||||
void R_FreeDeadParticles( struct particle_s **ppparticles );
|
||||
void CL_AddClientResource( const char *filename, int type );
|
||||
void CL_AddClientResources( void );
|
||||
int CL_FxBlend( cl_entity_t *e );
|
||||
|
@ -1019,12 +1056,14 @@ void Con_Bottom( void );
|
|||
void Con_Top( void );
|
||||
void Con_PageDown( int lines );
|
||||
void Con_PageUp( int lines );
|
||||
void Con_LoadHistory( void );
|
||||
|
||||
//
|
||||
// s_main.c
|
||||
//
|
||||
void S_StreamRawSamples( int samples, int rate, int width, int channels, const byte *data );
|
||||
void S_StartBackgroundTrack( const char *intro, const char *loop, long position, qboolean fullpath );
|
||||
void S_StreamAviSamples( void *Avi, int entnum, float fvol, float attn, float synctime );
|
||||
void S_StartBackgroundTrack( const char *intro, const char *loop, int position, qboolean fullpath );
|
||||
void S_StopBackgroundTrack( void );
|
||||
void S_StreamSetPause( int pause );
|
||||
void S_StartStreaming( void );
|
||||
|
|
|
@ -37,7 +37,6 @@ static qboolean g_utf8 = false;
|
|||
#define COLOR_DEFAULT '7'
|
||||
#define CON_HISTORY 64
|
||||
#define MAX_DBG_NOTIFY 128
|
||||
#define CON_MAXCMDS 4096 // auto-complete intermediate list
|
||||
#define CON_NUMFONTS 3 // maxfonts
|
||||
|
||||
#define CON_LINES( i ) (con.lines[(con.lines_first + (i)) % con.maxlines])
|
||||
|
@ -60,14 +59,6 @@ rgba_t g_color_table[8] =
|
|||
{ 240, 180, 24, 255 }, // default color (can be changed by user)
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
string buffer;
|
||||
int cursor;
|
||||
int scroll;
|
||||
int widthInChars;
|
||||
} field_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
string szNotify;
|
||||
|
@ -123,21 +114,15 @@ typedef struct
|
|||
field_t historyLines[CON_HISTORY];
|
||||
int historyLine; // the line being displayed from history buffer will be <= nextHistoryLine
|
||||
int nextHistoryLine; // the last line in the history buffer, not masked
|
||||
field_t backup;
|
||||
|
||||
notify_t notify[MAX_DBG_NOTIFY]; // for Con_NXPrintf
|
||||
qboolean draw_notify; // true if we have NXPrint message
|
||||
|
||||
// console auto-complete
|
||||
string shortestMatch;
|
||||
field_t *completionField; // con.input or dedicated server fake field-line
|
||||
const char *completionString;
|
||||
const char *completionBuffer;
|
||||
char *cmds[CON_MAXCMDS];
|
||||
int matchCount;
|
||||
} console_t;
|
||||
|
||||
static console_t con;
|
||||
|
||||
void Con_ClearField( field_t *edit );
|
||||
void Field_CharEvent( field_t *edit, int ch );
|
||||
|
||||
/*
|
||||
|
@ -193,18 +178,6 @@ void Con_ClearNotify( void )
|
|||
CON_LINES( i ).addtime = 0.0;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Con_ClearField
|
||||
================
|
||||
*/
|
||||
void Con_ClearField( field_t *edit )
|
||||
{
|
||||
memset( edit->buffer, 0, MAX_STRING );
|
||||
edit->cursor = 0;
|
||||
edit->scroll = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Con_ClearTyping
|
||||
|
@ -217,13 +190,7 @@ void Con_ClearTyping( void )
|
|||
Con_ClearField( &con.input );
|
||||
con.input.widthInChars = con.linewidth;
|
||||
|
||||
// free the old autocomplete list
|
||||
for( i = 0; i < con.matchCount; i++ )
|
||||
{
|
||||
freestring( con.cmds[i] );
|
||||
}
|
||||
|
||||
con.matchCount = 0;
|
||||
Cmd_AutoCompleteClear();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -474,7 +441,7 @@ void Con_CheckResize( void )
|
|||
int i, width;
|
||||
|
||||
if( con.curFont && con.curFont->hFontTexture )
|
||||
charWidth = con.curFont->charWidths['M'] - 1;
|
||||
charWidth = con.curFont->charWidths['O'] - 1;
|
||||
|
||||
width = ( glState.width / charWidth ) - 2;
|
||||
if( !glw_state.initialized ) width = (640 / 5);
|
||||
|
@ -565,12 +532,12 @@ 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, NULL );
|
||||
font->hFontTexture = GL_LoadTexture( fontname, NULL, 0, TF_FONT|TF_KEEP_SOURCE );
|
||||
R_GetTextureParms( &fontWidth, NULL, font->hFontTexture );
|
||||
|
||||
if( font->hFontTexture && fontWidth != 0 )
|
||||
{
|
||||
font->charHeight = fontWidth / 16;
|
||||
font->charHeight = fontWidth / 16 * con_fontscale->value;
|
||||
font->type = FONT_FIXED;
|
||||
|
||||
// build fixed rectangles
|
||||
|
@ -580,7 +547,7 @@ static qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font )
|
|||
font->fontRc[i].right = font->fontRc[i].left + fontWidth / 16;
|
||||
font->fontRc[i].top = (i / 16) * (fontWidth / 16);
|
||||
font->fontRc[i].bottom = font->fontRc[i].top + fontWidth / 16;
|
||||
font->charWidths[i] = fontWidth / 16;
|
||||
font->charWidths[i] = fontWidth / 16 * con_fontscale->value;
|
||||
}
|
||||
font->valid = true;
|
||||
}
|
||||
|
@ -601,7 +568,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, NULL );
|
||||
font->hFontTexture = GL_LoadTexture( fontname, NULL, 0, TF_FONT|TF_NEAREST );
|
||||
R_GetTextureParms( &fontWidth, NULL, font->hFontTexture );
|
||||
|
||||
// setup consolefont
|
||||
|
@ -896,6 +863,7 @@ 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;
|
||||
|
@ -904,14 +872,24 @@ static int Con_DrawGenericChar( int x, int y, int number, rgba_t color )
|
|||
return 0;
|
||||
|
||||
number = Con_UtfProcessChar(number);
|
||||
if( number < 32 )
|
||||
if( !number )
|
||||
return 0;
|
||||
|
||||
if( y < -con.curFont->charHeight )
|
||||
return 0;
|
||||
|
||||
rc = &con.curFont->fontRc[number];
|
||||
glt = R_GetTexture( con.curFont->hFontTexture );
|
||||
width = glt->srcWidth;
|
||||
height = glt->srcHeight;
|
||||
|
||||
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 );
|
||||
|
||||
// calc rectangle
|
||||
|
@ -1102,6 +1080,61 @@ int Con_DrawString( int x, int y, const char *string, rgba_t setColor )
|
|||
return Con_DrawGenericString( x, y, string, setColor, false, -1 );
|
||||
}
|
||||
|
||||
void Con_LoadHistory( void )
|
||||
{
|
||||
const char *aFile = FS_LoadFile( "console_history.txt", NULL, true );
|
||||
const char *pLine = aFile, *pFile = aFile;
|
||||
int i;
|
||||
|
||||
if( !aFile )
|
||||
return;
|
||||
|
||||
while( true )
|
||||
{
|
||||
if( !*pFile )
|
||||
break;
|
||||
if( *pFile == '\n')
|
||||
{
|
||||
int len = pFile - pLine + 1;
|
||||
if( len > 255 ) len = 255;
|
||||
Con_ClearField( &con.historyLines[con.nextHistoryLine] );
|
||||
field_t *f = &con.historyLines[con.nextHistoryLine % CON_HISTORY];
|
||||
f->widthInChars = con.linewidth;
|
||||
f->cursor = len - 1;
|
||||
Q_strncpy( f->buffer, pLine, len);
|
||||
con.nextHistoryLine++;
|
||||
pLine = pFile + 1;
|
||||
}
|
||||
pFile++;
|
||||
}
|
||||
|
||||
for( i = con.nextHistoryLine; i < CON_HISTORY; i++ )
|
||||
{
|
||||
Con_ClearField( &con.historyLines[i] );
|
||||
con.historyLines[i].widthInChars = con.linewidth;
|
||||
}
|
||||
|
||||
con.historyLine = con.nextHistoryLine;
|
||||
|
||||
}
|
||||
|
||||
void Con_SaveHistory( void )
|
||||
{
|
||||
int historyStart = con.nextHistoryLine - CON_HISTORY;
|
||||
int i;
|
||||
file_t *f;
|
||||
|
||||
if( historyStart < 0 )
|
||||
historyStart = 0;
|
||||
|
||||
f = FS_Open("console_history.txt", "w", true );
|
||||
|
||||
for( i = historyStart; i < con.nextHistoryLine; i++ )
|
||||
FS_Printf( f, "%s\n", con.historyLines[i % CON_HISTORY].buffer );
|
||||
|
||||
FS_Close(f);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Con_Init
|
||||
|
@ -1124,9 +1157,9 @@ void Con_Init( void )
|
|||
|
||||
// init the console buffer
|
||||
con.bufsize = CON_TEXTSIZE;
|
||||
con.buffer = (char *)Z_Malloc( con.bufsize );
|
||||
con.buffer = (char *)Z_Calloc( con.bufsize );
|
||||
con.maxlines = CON_MAXLINES;
|
||||
con.lines = (con_lineinfo_t *)Z_Malloc( con.maxlines * sizeof( *con.lines ));
|
||||
con.lines = (con_lineinfo_t *)Z_Calloc( con.maxlines * sizeof( *con.lines ));
|
||||
con.lines_first = con.lines_count = 0;
|
||||
con.num_times = CON_TIMES; // default as 4
|
||||
|
||||
|
@ -1138,12 +1171,6 @@ void Con_Init( void )
|
|||
Con_ClearField( &con.chat );
|
||||
con.chat.widthInChars = con.linewidth;
|
||||
|
||||
for( i = 0; i < CON_HISTORY; i++ )
|
||||
{
|
||||
Con_ClearField( &con.historyLines[i] );
|
||||
con.historyLines[i].widthInChars = con.linewidth;
|
||||
}
|
||||
|
||||
Cmd_AddCommand( "toggleconsole", Con_ToggleConsole_f, "opens or closes the console" );
|
||||
Cmd_AddCommand( "con_color", Con_SetColor_f, "set a custom console color" );
|
||||
Cmd_AddCommand( "clear", Con_Clear_f, "clear console history" );
|
||||
|
@ -1152,7 +1179,7 @@ void Con_Init( void )
|
|||
Cmd_AddCommand( "contimes", Con_SetTimes_f, "change number of console overlay lines (4-64)" );
|
||||
con.initialized = true;
|
||||
|
||||
MsgDev( D_INFO, "Console initialized.\n" );
|
||||
Con_Printf( "Console initialized.\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1172,6 +1199,7 @@ void Con_Shutdown( void )
|
|||
|
||||
con.buffer = NULL;
|
||||
con.lines = NULL;
|
||||
Con_SaveHistory();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1368,216 +1396,15 @@ EDIT FIELDS
|
|||
=============================================================================
|
||||
*/
|
||||
/*
|
||||
===============
|
||||
Con_AddCommandToList
|
||||
|
||||
===============
|
||||
================
|
||||
Con_ClearField
|
||||
================
|
||||
*/
|
||||
static void Con_AddCommandToList( const char *s, const char *unused1, const char *unused2, void *unused3 )
|
||||
void Con_ClearField( field_t *edit )
|
||||
{
|
||||
if( *s == '@' ) return; // never show system cvars or cmds
|
||||
if( con.matchCount >= CON_MAXCMDS ) return; // list is full
|
||||
|
||||
if( Q_strnicmp( s, con.completionString, Q_strlen( con.completionString )))
|
||||
return; // no match
|
||||
|
||||
con.cmds[con.matchCount++] = copystring( s );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Con_SortCmds
|
||||
=================
|
||||
*/
|
||||
static int Con_SortCmds( const char **arg1, const char **arg2 )
|
||||
{
|
||||
return Q_stricmp( *arg1, *arg2 );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_PrintCmdMatches
|
||||
===============
|
||||
*/
|
||||
static void Con_PrintCmdMatches( const char *s, const char *unused1, const char *m, void *unused2 )
|
||||
{
|
||||
if( !Q_strnicmp( s, con.shortestMatch, Q_strlen( con.shortestMatch )))
|
||||
{
|
||||
if( COM_CheckString( m )) Con_Printf( " %s ^3\"%s\"\n", s, m );
|
||||
else Con_Printf( " %s\n", s ); // variable or command without description
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_PrintCvarMatches
|
||||
===============
|
||||
*/
|
||||
static void Con_PrintCvarMatches( const char *s, const char *value, const char *m, void *unused2 )
|
||||
{
|
||||
if( !Q_strnicmp( s, con.shortestMatch, Q_strlen( con.shortestMatch )))
|
||||
{
|
||||
if( COM_CheckString( m )) Con_Printf( " %s (%s) ^3\"%s\"\n", s, value, m );
|
||||
else Con_Printf( " %s (%s)\n", s, value ); // variable or command without description
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_ConcatRemaining
|
||||
===============
|
||||
*/
|
||||
static void Con_ConcatRemaining( const char *src, const char *start )
|
||||
{
|
||||
const char *arg;
|
||||
int i;
|
||||
|
||||
arg = Q_strstr( src, start );
|
||||
|
||||
if( !arg )
|
||||
{
|
||||
for( i = 1; i < Cmd_Argc(); i++ )
|
||||
{
|
||||
Q_strncat( con.completionField->buffer, " ", sizeof( con.completionField->buffer ));
|
||||
arg = Cmd_Argv( i );
|
||||
while( *arg )
|
||||
{
|
||||
if( *arg == ' ' )
|
||||
{
|
||||
Q_strncat( con.completionField->buffer, "\"", sizeof( con.completionField->buffer ));
|
||||
break;
|
||||
}
|
||||
arg++;
|
||||
}
|
||||
|
||||
Q_strncat( con.completionField->buffer, Cmd_Argv( i ), sizeof( con.completionField->buffer ));
|
||||
if( *arg == ' ' ) Q_strncat( con.completionField->buffer, "\"", sizeof( con.completionField->buffer ));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
arg += Q_strlen( start );
|
||||
Q_strncat( con.completionField->buffer, arg, sizeof( con.completionField->buffer ));
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_CompleteCommand
|
||||
|
||||
perform Tab expansion
|
||||
===============
|
||||
*/
|
||||
void Con_CompleteCommand( field_t *field )
|
||||
{
|
||||
field_t temp;
|
||||
string filename;
|
||||
qboolean nextcmd;
|
||||
int i;
|
||||
|
||||
// setup the completion field
|
||||
con.completionField = field;
|
||||
|
||||
// only look at the first token for completion purposes
|
||||
Cmd_TokenizeString( con.completionField->buffer );
|
||||
|
||||
nextcmd = ( con.completionField->buffer[Q_strlen( con.completionField->buffer ) - 1] == ' ' ) ? true : false;
|
||||
|
||||
con.completionString = Cmd_Argv( 0 );
|
||||
con.completionBuffer = Cmd_Argv( 1 );
|
||||
|
||||
// skip backslash
|
||||
while( *con.completionString && ( *con.completionString == '\\' || *con.completionString == '/' ))
|
||||
con.completionString++;
|
||||
|
||||
// skip backslash
|
||||
while( *con.completionBuffer && ( *con.completionBuffer == '\\' || *con.completionBuffer == '/' ))
|
||||
con.completionBuffer++;
|
||||
|
||||
if( !Q_strlen( con.completionString ))
|
||||
return;
|
||||
|
||||
// free the old autocomplete list
|
||||
for( i = 0; i < con.matchCount; i++ )
|
||||
{
|
||||
if( con.cmds[i] != NULL )
|
||||
{
|
||||
Mem_Free( con.cmds[i] );
|
||||
con.cmds[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
con.matchCount = 0;
|
||||
con.shortestMatch[0] = 0;
|
||||
|
||||
// find matching commands and variables
|
||||
Cmd_LookupCmds( NULL, NULL, Con_AddCommandToList );
|
||||
Cvar_LookupVars( 0, NULL, NULL, Con_AddCommandToList );
|
||||
|
||||
if( !con.matchCount ) return; // no matches
|
||||
|
||||
memcpy( &temp, con.completionField, sizeof( field_t ));
|
||||
|
||||
// autocomplete second arg
|
||||
if(( Cmd_Argc() == 2 ) || (( Cmd_Argc() == 1 ) && nextcmd ))
|
||||
{
|
||||
if( !Q_strlen( con.completionBuffer ))
|
||||
return;
|
||||
|
||||
if( Cmd_AutocompleteName( con.completionBuffer, filename, sizeof( filename )))
|
||||
{
|
||||
Q_sprintf( con.completionField->buffer, "%s %s", Cmd_Argv( 0 ), filename );
|
||||
con.completionField->cursor = Q_strlen( con.completionField->buffer );
|
||||
}
|
||||
|
||||
// don't adjusting cursor pos if we nothing found
|
||||
return;
|
||||
}
|
||||
else if( Cmd_Argc() >= 3 )
|
||||
{
|
||||
// disable autocomplete for all next args
|
||||
return;
|
||||
}
|
||||
|
||||
if( con.matchCount == 1 )
|
||||
{
|
||||
Q_sprintf( con.completionField->buffer, "\\%s", con.cmds[0] );
|
||||
if( Cmd_Argc() == 1 ) Q_strncat( con.completionField->buffer, " ", sizeof( con.completionField->buffer ));
|
||||
else Con_ConcatRemaining( temp.buffer, con.completionString );
|
||||
con.completionField->cursor = Q_strlen( con.completionField->buffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
char *first, *last;
|
||||
int len = 0;
|
||||
|
||||
qsort( con.cmds, con.matchCount, sizeof( char* ), Con_SortCmds );
|
||||
|
||||
// find the number of matching characters between the first and
|
||||
// the last element in the list and copy it
|
||||
first = con.cmds[0];
|
||||
last = con.cmds[con.matchCount-1];
|
||||
|
||||
while( *first && *last && Q_tolower( *first ) == Q_tolower( *last ))
|
||||
{
|
||||
first++;
|
||||
last++;
|
||||
|
||||
con.shortestMatch[len] = con.cmds[0][len];
|
||||
len++;
|
||||
}
|
||||
con.shortestMatch[len] = 0;
|
||||
|
||||
// multiple matches, complete to shortest
|
||||
Q_sprintf( con.completionField->buffer, "\\%s", con.shortestMatch );
|
||||
con.completionField->cursor = Q_strlen( con.completionField->buffer );
|
||||
Con_ConcatRemaining( temp.buffer, con.completionString );
|
||||
|
||||
Con_Printf( "]%s\n", con.completionField->buffer );
|
||||
|
||||
// run through again, printing matches
|
||||
Cmd_LookupCmds( NULL, NULL, Con_PrintCmdMatches );
|
||||
Cvar_LookupVars( 0, NULL, NULL, Con_PrintCvarMatches );
|
||||
}
|
||||
memset(edit->buffer, 0, MAX_STRING);
|
||||
edit->cursor = 0;
|
||||
edit->scroll = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1865,6 +1692,7 @@ void Key_Console( int key )
|
|||
|
||||
Con_ClearField( &con.input );
|
||||
con.input.widthInChars = con.linewidth;
|
||||
Con_Bottom();
|
||||
|
||||
if( cls.state == ca_disconnected )
|
||||
{
|
||||
|
@ -1878,12 +1706,15 @@ void Key_Console( int key )
|
|||
if( key == K_TAB )
|
||||
{
|
||||
Con_CompleteCommand( &con.input );
|
||||
Con_Bottom();
|
||||
return;
|
||||
}
|
||||
|
||||
// command history (ctrl-p ctrl-n for unix style)
|
||||
if(( key == K_MWHEELUP && Key_IsDown( K_SHIFT )) || ( key == K_UPARROW ) || (( Q_tolower(key) == 'p' ) && Key_IsDown( K_CTRL )))
|
||||
{
|
||||
if( con.historyLine == con.nextHistoryLine )
|
||||
con.backup = con.input;
|
||||
if( con.nextHistoryLine - con.historyLine < CON_HISTORY && con.historyLine > 0 )
|
||||
con.historyLine--;
|
||||
con.input = con.historyLines[con.historyLine % CON_HISTORY];
|
||||
|
@ -1892,9 +1723,13 @@ void Key_Console( int key )
|
|||
|
||||
if(( key == K_MWHEELDOWN && Key_IsDown( K_SHIFT )) || ( key == K_DOWNARROW ) || (( Q_tolower(key) == 'n' ) && Key_IsDown( K_CTRL )))
|
||||
{
|
||||
if( con.historyLine == con.nextHistoryLine ) return;
|
||||
if( con.historyLine >= con.nextHistoryLine - 1 )
|
||||
con.input = con.backup;
|
||||
else
|
||||
{
|
||||
con.historyLine++;
|
||||
con.input = con.historyLines[con.historyLine % CON_HISTORY];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2201,7 +2036,7 @@ void Con_DrawSolidConsole( int lines )
|
|||
// draw the background
|
||||
GL_SetRenderMode( kRenderNormal );
|
||||
pglColor4ub( 255, 255, 255, 255 ); // to prevent grab color from screenfade
|
||||
R_DrawStretchPic( 0, lines - glState.height, glState.width, glState.height, 0, 0, 1, 1, con.background );
|
||||
R_DrawStretchPic( 0, lines - glState.width * 3 / 4, glState.width, glState.width * 3 / 4, 0, 0, 1, 1, con.background );
|
||||
|
||||
if( !con.curFont || !host.allow_console )
|
||||
return; // nothing to draw
|
||||
|
@ -2215,7 +2050,9 @@ void Con_DrawSolidConsole( int lines )
|
|||
|
||||
memcpy( color, g_color_table[7], sizeof( color ));
|
||||
|
||||
Q_snprintf( curbuild, MAX_STRING, "%s %i/%s (hw build %i)", XASH_ENGINE_NAME, PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( ));
|
||||
|
||||
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;
|
||||
stringLen = Con_StringLength( curbuild );
|
||||
|
@ -2364,9 +2201,13 @@ void Con_DrawVersion( void )
|
|||
return;
|
||||
}
|
||||
|
||||
if( host.force_draw_version_time > host.realtime )
|
||||
host.force_draw_version = false;
|
||||
|
||||
if( host.force_draw_version || draw_version )
|
||||
Q_snprintf( curbuild, MAX_STRING, "%s v%i/%s (build %i)", XASH_ENGINE_NAME, PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( ));
|
||||
else Q_snprintf( curbuild, MAX_STRING, "v%i/%s (build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( ));
|
||||
Q_snprintf( curbuild, MAX_STRING, "%s v%i/%s (%s-%s build %i)", XASH_ENGINE_NAME, PROTOCOL_VERSION, XASH_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
|
||||
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;
|
||||
stringLen = Con_StringLength( curbuild );
|
||||
|
@ -2481,28 +2322,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, NULL );
|
||||
con.background = 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, NULL );
|
||||
con.background = 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, NULL );
|
||||
con.background = 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, NULL );
|
||||
con.background = 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, NULL );
|
||||
con.background = 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, NULL );
|
||||
con.background = GL_LoadTexture( "cached/loading", NULL, 0, TF_IMAGE );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2511,7 +2352,7 @@ void Con_VidInit( void )
|
|||
{
|
||||
qboolean draw_to_console = false;
|
||||
int length = 0;
|
||||
gltexture_t *chars;
|
||||
gl_texture_t *chars;
|
||||
|
||||
// NOTE: only these games want to draw build number into console background
|
||||
if( !Q_stricmp( FS_Gamedir(), "id1" ))
|
||||
|
@ -2537,13 +2378,13 @@ void Con_VidInit( void )
|
|||
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, NULL );
|
||||
con.background = 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, NULL );
|
||||
con.background = GL_LoadTexture( "gfx/conback.lmp", NULL, 0, TF_IMAGE );
|
||||
}
|
||||
|
||||
// missed console image will be replaced as gray background like X-Ray or Crysis
|
||||
|
@ -2563,32 +2404,6 @@ void Con_InvalidateFonts( void )
|
|||
con.curFont = con.lastUsedFont = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=========
|
||||
Cmd_AutoComplete
|
||||
|
||||
NOTE: input string must be equal or longer than MAX_STRING
|
||||
=========
|
||||
*/
|
||||
void Cmd_AutoComplete( char *complete_string )
|
||||
{
|
||||
field_t input;
|
||||
|
||||
if( !complete_string || !*complete_string )
|
||||
return;
|
||||
|
||||
// setup input
|
||||
Q_strncpy( input.buffer, complete_string, sizeof( input.buffer ));
|
||||
input.cursor = input.scroll = 0;
|
||||
|
||||
Con_CompleteCommand( &input );
|
||||
|
||||
// setup output
|
||||
if( input.buffer[0] == '\\' || input.buffer[0] == '/' )
|
||||
Q_strncpy( complete_string, input.buffer + 1, sizeof( input.buffer ));
|
||||
else Q_strncpy( complete_string, input.buffer, sizeof( input.buffer ));
|
||||
}
|
||||
|
||||
/*
|
||||
=========
|
||||
Con_FastClose
|
||||
|
|
|
@ -318,10 +318,10 @@ void GL_MakeAliasModelDisplayLists( model_t *m )
|
|||
// save the data out
|
||||
m_pAliasHeader->poseverts = g_numorder;
|
||||
|
||||
m_pAliasHeader->commands = Mem_Alloc( m->mempool, g_numcommands * 4 );
|
||||
m_pAliasHeader->commands = Mem_Malloc( m->mempool, g_numcommands * 4 );
|
||||
memcpy( m_pAliasHeader->commands, g_commands, g_numcommands * 4 );
|
||||
|
||||
m_pAliasHeader->posedata = Mem_Alloc( m->mempool, m_pAliasHeader->numposes * m_pAliasHeader->poseverts * sizeof( trivertex_t ));
|
||||
m_pAliasHeader->posedata = Mem_Malloc( m->mempool, m_pAliasHeader->numposes * m_pAliasHeader->poseverts * sizeof( trivertex_t ));
|
||||
verts = m_pAliasHeader->posedata;
|
||||
|
||||
for( i = 0; i < m_pAliasHeader->numposes; i++ )
|
||||
|
@ -433,6 +433,8 @@ rgbdata_t *Mod_CreateSkinData( model_t *mod, byte *data, int width, int height )
|
|||
skin.palette = (byte *)&clgame.palette;
|
||||
skin.size = width * height;
|
||||
|
||||
if( !Image_CustomPalette() )
|
||||
{
|
||||
for( i = 0; i < skin.width * skin.height; i++ )
|
||||
{
|
||||
if( data[i] > 224 && data[i] != 255 )
|
||||
|
@ -441,6 +443,7 @@ rgbdata_t *Mod_CreateSkinData( model_t *mod, byte *data, int width, int height )
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
COM_FileBase( loadmodel->name, name );
|
||||
|
||||
|
@ -453,7 +456,7 @@ rgbdata_t *Mod_CreateSkinData( model_t *mod, byte *data, int width, int height )
|
|||
i = mod->numtextures;
|
||||
mod->textures = (texture_t **)Mem_Realloc( mod->mempool, mod->textures, ( i + 1 ) * sizeof( texture_t* ));
|
||||
size = width * height + 768;
|
||||
tx = Mem_Alloc( mod->mempool, sizeof( *tx ) + size );
|
||||
tx = Mem_Calloc( mod->mempool, sizeof( *tx ) + size );
|
||||
mod->textures[i] = tx;
|
||||
|
||||
Q_strncpy( tx->name, "DM_Skin", sizeof( tx->name ));
|
||||
|
@ -478,16 +481,19 @@ rgbdata_t *Mod_CreateSkinData( model_t *mod, byte *data, int width, int height )
|
|||
void *Mod_LoadSingleSkin( daliasskintype_t *pskintype, int skinnum, int size )
|
||||
{
|
||||
string name, lumaname;
|
||||
string checkname;
|
||||
rgbdata_t *pic;
|
||||
|
||||
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 )
|
||||
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, false );
|
||||
m_pAliasHeader->gl_texturenum[skinnum][3] = GL_LoadTextureInternal( name, pic, 0 );
|
||||
FS_FreeImage( pic );
|
||||
|
||||
if( R_GetTexture( m_pAliasHeader->gl_texturenum[skinnum][0] )->flags & TF_HAS_LUMA )
|
||||
|
@ -496,7 +502,7 @@ void *Mod_LoadSingleSkin( daliasskintype_t *pskintype, int skinnum, int size )
|
|||
m_pAliasHeader->fb_texturenum[skinnum][0] =
|
||||
m_pAliasHeader->fb_texturenum[skinnum][1] =
|
||||
m_pAliasHeader->fb_texturenum[skinnum][2] =
|
||||
m_pAliasHeader->fb_texturenum[skinnum][3] = GL_LoadTextureInternal( lumaname, pic, TF_MAKELUMA, false );
|
||||
m_pAliasHeader->fb_texturenum[skinnum][3] = GL_LoadTextureInternal( lumaname, pic, TF_MAKELUMA );
|
||||
FS_FreeImage( pic );
|
||||
}
|
||||
|
||||
|
@ -521,14 +527,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, false );
|
||||
m_pAliasHeader->gl_texturenum[skinnum][i & 3] = GL_LoadTextureInternal( name, pic, 0 );
|
||||
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, false );
|
||||
m_pAliasHeader->fb_texturenum[skinnum][i & 3] = GL_LoadTextureInternal( lumaname, pic, TF_MAKELUMA );
|
||||
FS_FreeImage( pic );
|
||||
}
|
||||
|
||||
|
@ -618,10 +624,9 @@ void Mod_LoadAliasModel( model_t *mod, const void *buffer, qboolean *loaded )
|
|||
daliashdr_t *pinmodel;
|
||||
stvert_t *pinstverts;
|
||||
dtriangle_t *pintriangles;
|
||||
int numframes, size;
|
||||
daliasframetype_t *pframetype;
|
||||
daliasskintype_t *pskintype;
|
||||
int i, j;
|
||||
int i, j, size;
|
||||
|
||||
if( loaded ) *loaded = false;
|
||||
pinmodel = (daliashdr_t *)buffer;
|
||||
|
@ -629,17 +634,20 @@ void Mod_LoadAliasModel( model_t *mod, const void *buffer, qboolean *loaded )
|
|||
|
||||
if( i != ALIAS_VERSION )
|
||||
{
|
||||
MsgDev( D_ERROR, "%s has wrong version number (%i should be %i)\n", mod->name, i, ALIAS_VERSION );
|
||||
Con_DPrintf( S_ERROR "%s has wrong version number (%i should be %i)\n", mod->name, i, ALIAS_VERSION );
|
||||
return;
|
||||
}
|
||||
|
||||
if( pinmodel->numverts <= 0 || pinmodel->numtris <= 0 || pinmodel->numframes <= 0 )
|
||||
return; // how to possible is make that?
|
||||
|
||||
mod->mempool = Mem_AllocPool( va( "^2%s^7", mod->name ));
|
||||
|
||||
// allocate space for a working header, plus all the data except the frames,
|
||||
// skin and group info
|
||||
size = sizeof( aliashdr_t ) + (pinmodel->numframes - 1) * sizeof( maliasframedesc_t );
|
||||
|
||||
m_pAliasHeader = Mem_Alloc( mod->mempool, size );
|
||||
m_pAliasHeader = Mem_Calloc( mod->mempool, size );
|
||||
mod->flags = pinmodel->flags; // share effects flags
|
||||
|
||||
// endian-adjust and copy the data, starting with the alias model header
|
||||
|
@ -648,33 +656,12 @@ void Mod_LoadAliasModel( model_t *mod, const void *buffer, qboolean *loaded )
|
|||
m_pAliasHeader->skinwidth = pinmodel->skinwidth;
|
||||
m_pAliasHeader->skinheight = pinmodel->skinheight;
|
||||
m_pAliasHeader->numverts = pinmodel->numverts;
|
||||
|
||||
if( m_pAliasHeader->numverts <= 0 )
|
||||
{
|
||||
MsgDev( D_ERROR, "model %s has no vertices\n", mod->name );
|
||||
return;
|
||||
}
|
||||
m_pAliasHeader->numtris = pinmodel->numtris;
|
||||
m_pAliasHeader->numframes = pinmodel->numframes;
|
||||
|
||||
if( m_pAliasHeader->numverts > MAXALIASVERTS )
|
||||
{
|
||||
MsgDev( D_ERROR, "model %s has too many vertices\n", mod->name );
|
||||
return;
|
||||
}
|
||||
|
||||
m_pAliasHeader->numtris = pinmodel->numtris;
|
||||
|
||||
if( m_pAliasHeader->numtris <= 0 )
|
||||
{
|
||||
MsgDev( D_ERROR, "model %s has no triangles\n", mod->name );
|
||||
return;
|
||||
}
|
||||
|
||||
m_pAliasHeader->numframes = pinmodel->numframes;
|
||||
numframes = m_pAliasHeader->numframes;
|
||||
|
||||
if( numframes < 1 )
|
||||
{
|
||||
MsgDev( D_ERROR, "Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes );
|
||||
Con_DPrintf( S_ERROR "model %s has too many vertices\n", mod->name );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -718,7 +705,7 @@ void Mod_LoadAliasModel( model_t *mod, const void *buffer, qboolean *loaded )
|
|||
pframetype = (daliasframetype_t *)&pintriangles[m_pAliasHeader->numtris];
|
||||
g_posenum = 0;
|
||||
|
||||
for( i = 0; i < numframes; i++ )
|
||||
for( i = 0; i < m_pAliasHeader->numframes; i++ )
|
||||
{
|
||||
aliasframetype_t frametype = pframetype->type;
|
||||
|
||||
|
@ -863,41 +850,45 @@ void R_AliasDynamicLight( cl_entity_t *ent, alight_t *plight )
|
|||
VectorScale( lightDir, 2048.0f, vecEnd );
|
||||
VectorAdd( vecEnd, vecSrc, vecEnd );
|
||||
|
||||
light = R_LightVec( vecSrc, vecEnd, g_alias.lightspot );
|
||||
|
||||
VectorScale( lightDir, 2048.0f, vecEnd );
|
||||
VectorAdd( vecEnd, vecSrc, vecEnd );
|
||||
light = R_LightVec( vecSrc, vecEnd, g_alias.lightspot, g_alias.lightvec );
|
||||
|
||||
if( VectorIsNull( g_alias.lightvec ))
|
||||
{
|
||||
vecSrc[0] -= 16.0f;
|
||||
vecSrc[1] -= 16.0f;
|
||||
vecEnd[0] -= 16.0f;
|
||||
vecEnd[1] -= 16.0f;
|
||||
|
||||
gcolor = R_LightVec( vecSrc, vecEnd, NULL );
|
||||
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
|
||||
grad[0] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
|
||||
|
||||
vecSrc[0] += 32.0f;
|
||||
vecEnd[0] += 32.0f;
|
||||
|
||||
gcolor = R_LightVec( vecSrc, vecEnd, NULL );
|
||||
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
|
||||
grad[1] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
|
||||
|
||||
vecSrc[1] += 32.0f;
|
||||
vecEnd[1] += 32.0f;
|
||||
|
||||
gcolor = R_LightVec( vecSrc, vecEnd, NULL );
|
||||
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
|
||||
grad[2] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
|
||||
|
||||
vecSrc[0] -= 32.0f;
|
||||
vecEnd[0] -= 32.0f;
|
||||
|
||||
gcolor = R_LightVec( vecSrc, vecEnd, NULL );
|
||||
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
|
||||
grad[3] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
|
||||
|
||||
lightDir[0] = grad[0] - grad[1] - grad[2] + grad[3];
|
||||
lightDir[1] = grad[1] + grad[0] - grad[2] - grad[3];
|
||||
VectorNormalize( lightDir );
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy( g_alias.lightvec, lightDir );
|
||||
}
|
||||
}
|
||||
|
||||
VectorSet( finalLight, light.r, light.g, light.b );
|
||||
ent->cvFloorColor = light;
|
||||
|
@ -1189,15 +1180,18 @@ 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 )
|
||||
f = f + 1.0f;
|
||||
|
||||
g_alias.lerpfrac = bound( 0.0f, f, 1.0f );
|
||||
|
||||
if( e->player || e->curstate.movetype != MOVETYPE_STEP )
|
||||
return; // monsters only
|
||||
|
||||
// Con_Printf( "%4.2f %.2f %.2f\n", f, e->curstate.animtime, g_studio.time );
|
||||
// Con_Printf( "%4.2f %.2f %.2f\n", f, e->curstate.animtime, g_alias.time );
|
||||
VectorLerp( e->latched.prevorigin, f, e->curstate.origin, e->origin );
|
||||
|
||||
if( !VectorCompare( e->curstate.angles, e->latched.prevangles ))
|
||||
if( !VectorCompareEpsilon( e->curstate.angles, e->latched.prevangles, ON_EPSILON ))
|
||||
{
|
||||
vec4_t q, q1, q2;
|
||||
|
||||
|
@ -1236,7 +1230,7 @@ void R_SetupAliasFrame( cl_entity_t *e, aliashdr_t *paliashdr )
|
|||
else if( newframe >= paliashdr->numframes )
|
||||
{
|
||||
if( newframe > paliashdr->numframes )
|
||||
MsgDev( D_WARN, "R_GetAliasFrame: no such frame %d (%s)\n", newframe, e->model->name );
|
||||
Con_Reportf( S_WARN "R_GetAliasFrame: no such frame %d (%s)\n", newframe, e->model->name );
|
||||
newframe = paliashdr->numframes - 1;
|
||||
}
|
||||
|
||||
|
@ -1313,6 +1307,8 @@ static void R_AliasDrawLightTrace( cl_entity_t *e )
|
|||
{
|
||||
if( r_drawentities->value == 7 )
|
||||
{
|
||||
vec3_t origin;
|
||||
|
||||
pglDisable( GL_TEXTURE_2D );
|
||||
pglDisable( GL_DEPTH_TEST );
|
||||
|
||||
|
@ -1322,6 +1318,13 @@ static void R_AliasDrawLightTrace( cl_entity_t *e )
|
|||
pglVertex3fv( g_alias.lightspot );
|
||||
pglEnd();
|
||||
|
||||
pglBegin( GL_LINES );
|
||||
pglColor3f( 0, 0.5, 1 );
|
||||
VectorMA( g_alias.lightspot, -64.0f, g_alias.lightvec, origin );
|
||||
pglVertex3fv( g_alias.lightspot );
|
||||
pglVertex3fv( origin );
|
||||
pglEnd();
|
||||
|
||||
pglPointSize( 5.0f );
|
||||
pglColor3f( 1, 0, 0 );
|
||||
pglBegin( GL_POINTS );
|
||||
|
@ -1429,11 +1432,16 @@ void R_DrawAliasModel( cl_entity_t *e )
|
|||
R_AliasSetRemapColors( topcolor, bottomcolor );
|
||||
}
|
||||
|
||||
pglTranslatef( m_pAliasHeader->scale_origin[0], m_pAliasHeader->scale_origin[1], m_pAliasHeader->scale_origin[2] );
|
||||
|
||||
if( tr.fFlipViewModel )
|
||||
{
|
||||
pglTranslatef( m_pAliasHeader->scale_origin[0], -m_pAliasHeader->scale_origin[1], m_pAliasHeader->scale_origin[2] );
|
||||
pglScalef( m_pAliasHeader->scale[0], -m_pAliasHeader->scale[1], m_pAliasHeader->scale[2] );
|
||||
else pglScalef( m_pAliasHeader->scale[0], m_pAliasHeader->scale[1], m_pAliasHeader->scale[2] );
|
||||
}
|
||||
else
|
||||
{
|
||||
pglTranslatef( m_pAliasHeader->scale_origin[0], m_pAliasHeader->scale_origin[1], m_pAliasHeader->scale_origin[2] );
|
||||
pglScalef( m_pAliasHeader->scale[0], m_pAliasHeader->scale[1], m_pAliasHeader->scale[2] );
|
||||
}
|
||||
|
||||
anim = (int)(g_alias.time * 10) & 3;
|
||||
skin = bound( 0, RI.currententity->curstate.skin, m_pAliasHeader->numskins - 1 );
|
||||
|
@ -1443,7 +1451,17 @@ void R_DrawAliasModel( cl_entity_t *e )
|
|||
GL_Bind( XASH_TEXTURE0, tr.whiteTexture );
|
||||
else if( pinfo != NULL && pinfo->textures[skin] != 0 )
|
||||
GL_Bind( XASH_TEXTURE0, pinfo->textures[skin] ); // FIXME: allow remapping for skingroups someday
|
||||
else GL_Bind( XASH_TEXTURE0, m_pAliasHeader->gl_texturenum[skin][anim] );
|
||||
else
|
||||
{
|
||||
GL_Bind( XASH_TEXTURE0, m_pAliasHeader->gl_texturenum[skin][anim] );
|
||||
|
||||
if( FBitSet( R_GetTexture( m_pAliasHeader->gl_texturenum[skin][anim] )->flags, TF_HAS_ALPHA ))
|
||||
{
|
||||
pglEnable( GL_ALPHA_TEST );
|
||||
pglAlphaFunc( GL_GREATER, 0.0f );
|
||||
tr.blend = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
|
||||
|
@ -1470,6 +1488,8 @@ void R_DrawAliasModel( cl_entity_t *e )
|
|||
R_AliasDrawLightTrace( e );
|
||||
|
||||
pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
|
||||
pglAlphaFunc( GL_GREATER, DEFAULT_ALPHATEST );
|
||||
pglDisable( GL_ALPHA_TEST );
|
||||
|
||||
if( r_shadows.value )
|
||||
{
|
||||
|
|
|
@ -43,6 +43,25 @@ qboolean R_SpeedsMessage( char *out, size_t size )
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
R_Speeds_Printf
|
||||
|
||||
helper to print into r_speeds message
|
||||
==============
|
||||
*/
|
||||
void R_Speeds_Printf( const char *msg, ... )
|
||||
{
|
||||
va_list argptr;
|
||||
char text[2048];
|
||||
|
||||
va_start( argptr, msg );
|
||||
Q_vsprintf( text, msg, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
Q_strncat( r_speeds_msg, text, sizeof( r_speeds_msg ));
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
GL_BackendStartFrame
|
||||
|
@ -60,9 +79,17 @@ GL_BackendEndFrame
|
|||
*/
|
||||
void GL_BackendEndFrame( void )
|
||||
{
|
||||
mleaf_t *curleaf;
|
||||
|
||||
if( r_speeds->value <= 0 || !RI.drawWorld )
|
||||
return;
|
||||
|
||||
if( !RI.viewleaf )
|
||||
curleaf = cl.worldmodel->leafs;
|
||||
else curleaf = RI.viewleaf;
|
||||
|
||||
R_Speeds_Printf( "Renderer: ^1Engine^7\n\n" );
|
||||
|
||||
switch( (int)r_speeds->value )
|
||||
{
|
||||
case 1:
|
||||
|
@ -70,8 +97,8 @@ 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:
|
||||
Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "visible leafs:\n%3i leafs\ncurrent leaf %3i",
|
||||
r_stats.c_world_leafs, Mod_PointInLeaf( RI.pvsorigin, cl.worldmodel->nodes ) - cl.worldmodel->leafs );
|
||||
R_Speeds_Printf( "visible leafs:\n%3i leafs\ncurrent leaf %3i\n", r_stats.c_world_leafs, curleaf - cl.worldmodel->leafs );
|
||||
R_Speeds_Printf( "ReciusiveWorldNode: %3lf secs\nDrawTextureChains %lf\n", r_stats.t_world_node, r_stats.t_world_draw );
|
||||
break;
|
||||
case 3:
|
||||
Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i alias models drawn\n%3i studio models drawn\n%3i sprites drawn",
|
||||
|
@ -158,7 +185,7 @@ void GL_SelectTexture( GLint tmu )
|
|||
|
||||
if( tmu >= GL_MaxTextureUnits( ))
|
||||
{
|
||||
MsgDev( D_ERROR, "GL_SelectTexture: bad tmu state %i\n", tmu );
|
||||
Con_Reportf( S_ERROR "GL_SelectTexture: bad tmu state %i\n", tmu );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -222,6 +249,7 @@ GL_CleanupAllTextureUnits
|
|||
*/
|
||||
void GL_CleanupAllTextureUnits( void )
|
||||
{
|
||||
if( !glw_state.initialized ) return;
|
||||
// force to cleanup all the units
|
||||
GL_SelectTexture( GL_MaxTextureUnits() - 1 );
|
||||
GL_CleanUpTextureUnits( 0 );
|
||||
|
@ -250,7 +278,7 @@ void GL_TextureTarget( uint target )
|
|||
{
|
||||
if( glState.activeTMU < 0 || glState.activeTMU >= GL_MaxTextureUnits( ))
|
||||
{
|
||||
MsgDev( D_ERROR, "GL_TextureTarget: bad tmu state %i\n", glState.activeTMU );
|
||||
Con_Reportf( S_ERROR "GL_TextureTarget: bad tmu state %i\n", glState.activeTMU );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -463,14 +491,14 @@ qboolean VID_ScreenShot( const char *filename, int shot_type )
|
|||
int width = 0, height = 0;
|
||||
qboolean result;
|
||||
|
||||
r_shot = Mem_Alloc( r_temppool, sizeof( rgbdata_t ));
|
||||
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->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->palette = NULL;
|
||||
r_shot->buffer = Mem_Alloc( r_temppool, r_shot->size );
|
||||
r_shot->buffer = Mem_Malloc( r_temppool, r_shot->size );
|
||||
|
||||
// get screen frame
|
||||
pglReadPixels( 0, 0, r_shot->width, r_shot->height, GL_RGB, GL_UNSIGNED_BYTE, r_shot->buffer );
|
||||
|
@ -508,7 +536,7 @@ qboolean VID_ScreenShot( const char *filename, int shot_type )
|
|||
break;
|
||||
}
|
||||
|
||||
Image_Process( &r_shot, width, height, flags, NULL );
|
||||
Image_Process( &r_shot, width, height, flags, 0.0f );
|
||||
|
||||
// write image
|
||||
result = FS_SaveImage( filename, r_shot );
|
||||
|
@ -546,10 +574,10 @@ qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qbo
|
|||
RI.params |= RP_ENVVIEW; // do not render non-bmodel entities
|
||||
|
||||
// alloc space
|
||||
temp = Mem_Alloc( r_temppool, size * size * 3 );
|
||||
buffer = Mem_Alloc( r_temppool, size * size * 3 * 6 );
|
||||
r_shot = Mem_Alloc( r_temppool, sizeof( rgbdata_t ));
|
||||
r_side = Mem_Alloc( r_temppool, sizeof( rgbdata_t ));
|
||||
temp = Mem_Malloc( r_temppool, size * size * 3 );
|
||||
buffer = Mem_Malloc( r_temppool, size * size * 3 * 6 );
|
||||
r_shot = Mem_Calloc( r_temppool, sizeof( rgbdata_t ));
|
||||
r_side = Mem_Calloc( r_temppool, sizeof( rgbdata_t ));
|
||||
|
||||
// use client vieworg
|
||||
if( !vieworg ) vieworg = RI.vieworg;
|
||||
|
@ -577,7 +605,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, NULL );
|
||||
if( flags ) Image_Process( &r_side, 0, 0, flags, 0.0f );
|
||||
memcpy( buffer + (size * size * 3 * i), r_side->buffer, size * size * 3 );
|
||||
}
|
||||
|
||||
|
@ -617,7 +645,7 @@ was there. This is used to test for texture thrashing.
|
|||
*/
|
||||
void R_ShowTextures( void )
|
||||
{
|
||||
gltexture_t *image;
|
||||
gl_texture_t *image;
|
||||
float x, y, w, h;
|
||||
int total, start, end;
|
||||
int i, j, k, base_w, base_h;
|
||||
|
@ -626,7 +654,7 @@ void R_ShowTextures( void )
|
|||
static qboolean showHelp = true;
|
||||
string shortname;
|
||||
|
||||
if( !gl_showtextures->value )
|
||||
if( !CVAR_TO_BOOL( gl_showtextures ))
|
||||
return;
|
||||
|
||||
if( showHelp )
|
||||
|
@ -719,3 +747,95 @@ rebuild_page:
|
|||
CL_DrawCenterPrint ();
|
||||
pglFinish();
|
||||
}
|
||||
|
||||
#define POINT_SIZE 16.0f
|
||||
#define NODE_INTERVAL_X(x) (x * 16.0f)
|
||||
#define NODE_INTERVAL_Y(x) (x * 16.0f)
|
||||
|
||||
void R_DrawLeafNode( float x, float y, float scale )
|
||||
{
|
||||
float downScale = scale * 0.25f;// * POINT_SIZE;
|
||||
|
||||
R_DrawStretchPic( x - downScale * 0.5f, y - downScale * 0.5f, downScale, downScale, 0, 0, 1, 1, tr.particleTexture );
|
||||
}
|
||||
|
||||
void R_DrawNodeConnection( float x, float y, float x2, float y2 )
|
||||
{
|
||||
pglBegin( GL_LINES );
|
||||
pglVertex2f( x, y );
|
||||
pglVertex2f( x2, y2 );
|
||||
pglEnd();
|
||||
}
|
||||
|
||||
void R_ShowTree_r( mnode_t *node, float x, float y, float scale, int shownodes )
|
||||
{
|
||||
float downScale = scale * 0.8f;
|
||||
|
||||
downScale = Q_max( downScale, 1.0f );
|
||||
|
||||
if( !node ) return;
|
||||
|
||||
tr.recursion_level++;
|
||||
|
||||
if( node->contents < 0 )
|
||||
{
|
||||
mleaf_t *leaf = (mleaf_t *)node;
|
||||
|
||||
if( tr.recursion_level > tr.max_recursion )
|
||||
tr.max_recursion = tr.recursion_level;
|
||||
|
||||
if( shownodes == 1 )
|
||||
{
|
||||
if( cl.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 );
|
||||
else pglColor4f( 0.0f, 1.0f, 0.0f, 1.0f );
|
||||
R_DrawLeafNode( x, y, scale );
|
||||
}
|
||||
tr.recursion_level--;
|
||||
return;
|
||||
}
|
||||
|
||||
if( shownodes == 1 )
|
||||
{
|
||||
pglColor4f( 0.0f, 0.0f, 1.0f, 1.0f );
|
||||
R_DrawLeafNode( x, y, scale );
|
||||
}
|
||||
else if( shownodes == 2 )
|
||||
{
|
||||
R_DrawNodeConnection( x, y, x - scale, y + scale );
|
||||
R_DrawNodeConnection( x, y, x + scale, y + scale );
|
||||
}
|
||||
|
||||
R_ShowTree_r( node->children[1], x - scale, y + scale, downScale, shownodes );
|
||||
R_ShowTree_r( node->children[0], x + scale, y + scale, downScale, shownodes );
|
||||
|
||||
tr.recursion_level--;
|
||||
}
|
||||
|
||||
void R_ShowTree( void )
|
||||
{
|
||||
float x = (float)((glState.width - (int)POINT_SIZE) >> 1);
|
||||
float y = NODE_INTERVAL_Y(1.0);
|
||||
|
||||
if( !cl.worldmodel || !CVAR_TO_BOOL( r_showtree ))
|
||||
return;
|
||||
|
||||
tr.recursion_level = 0;
|
||||
|
||||
pglEnable( GL_BLEND );
|
||||
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
|
||||
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 );
|
||||
pglEnable( GL_TEXTURE_2D );
|
||||
pglLineWidth( 1.0f );
|
||||
|
||||
R_ShowTree_r( cl.worldmodel->nodes, x, y, tr.max_recursion * 3.5f, 1 );
|
||||
|
||||
Con_NPrintf( 0, "max recursion %d\n", tr.max_recursion );
|
||||
}
|
||||
|
|
|
@ -266,7 +266,7 @@ static qboolean R_BeamComputePoint( int beamEnt, vec3_t pt )
|
|||
|
||||
if( !ent )
|
||||
{
|
||||
MsgDev( D_ERROR, "R_BeamComputePoint: invalid entity %i\n", BEAMENT_ENTITY( beamEnt ));
|
||||
Con_DPrintf( S_ERROR "R_BeamComputePoint: invalid entity %i\n", BEAMENT_ENTITY( beamEnt ));
|
||||
VectorClear( pt );
|
||||
return false;
|
||||
}
|
||||
|
@ -418,8 +418,6 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f
|
|||
|
||||
div = 1.0f / (segments - 1);
|
||||
length *= 0.01f;
|
||||
|
||||
// UNDONE: Expose texture length scale factor to control "fuzziness"
|
||||
vStep = length * div; // Texture length texels per space pixel
|
||||
|
||||
// Scroll speed 3.5 -- initial texture position, scrolls 3.5/sec (1.0 is entire texture)
|
||||
|
@ -432,29 +430,21 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f
|
|||
segments = 16;
|
||||
div = 1.0f / ( segments - 1 );
|
||||
}
|
||||
|
||||
scale *= 100.0f;
|
||||
length = segments * 0.1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale *= length;
|
||||
scale *= length * 2.0;
|
||||
}
|
||||
|
||||
// Iterator to resample noise waveform (it needs to be generated in powers of 2)
|
||||
noiseStep = (int)((float)( NOISE_DIVISIONS - 1 ) * div * 65536.0f );
|
||||
|
||||
if( FBitSet( flags, FBEAM_SINENOISE ))
|
||||
noiseIndex = 0;
|
||||
else
|
||||
noiseIndex = noiseStep;
|
||||
|
||||
brightness = 1.0f;
|
||||
noiseIndex = 0;
|
||||
|
||||
if( FBitSet( flags, FBEAM_SHADEIN ))
|
||||
{
|
||||
brightness = 0;
|
||||
}
|
||||
|
||||
// Choose two vectors that are perpendicular to the beam
|
||||
R_BeamComputePerpendicular( delta, perp1 );
|
||||
|
@ -472,20 +462,6 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f
|
|||
|
||||
fraction = i * div;
|
||||
|
||||
if( FBitSet( flags, FBEAM_SHADEIN ) && FBitSet( flags, FBEAM_SHADEOUT ))
|
||||
{
|
||||
if( fraction < 0.5f ) brightness = 2.0f * fraction;
|
||||
else brightness = 2.0f * ( 1.0f - fraction );
|
||||
}
|
||||
else if( FBitSet( flags, FBEAM_SHADEIN ))
|
||||
{
|
||||
brightness = fraction;
|
||||
}
|
||||
else if( FBitSet( flags, FBEAM_SHADEOUT ))
|
||||
{
|
||||
brightness = 1.0f - fraction;
|
||||
}
|
||||
|
||||
VectorMA( source, fraction, delta, nextSeg.pos );
|
||||
|
||||
// distort using noise
|
||||
|
@ -553,6 +529,20 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f
|
|||
curSeg = nextSeg;
|
||||
segs_drawn++;
|
||||
|
||||
if( FBitSet( flags, FBEAM_SHADEIN ) && FBitSet( flags, FBEAM_SHADEOUT ))
|
||||
{
|
||||
if( fraction < 0.5f ) brightness = fraction;
|
||||
else brightness = ( 1.0f - fraction );
|
||||
}
|
||||
else if( FBitSet( flags, FBEAM_SHADEIN ))
|
||||
{
|
||||
brightness = fraction;
|
||||
}
|
||||
else if( FBitSet( flags, FBEAM_SHADEOUT ))
|
||||
{
|
||||
brightness = 1.0f - fraction;
|
||||
}
|
||||
|
||||
if( segs_drawn == total_segs )
|
||||
{
|
||||
// draw the last segment
|
||||
|
@ -1332,7 +1322,7 @@ CL_InitViewBeams
|
|||
*/
|
||||
void CL_InitViewBeams( void )
|
||||
{
|
||||
cl_viewbeams = Mem_Alloc( cls.mempool, sizeof( BEAM ) * GI->max_beams );
|
||||
cl_viewbeams = Mem_Calloc( cls.mempool, sizeof( BEAM ) * GI->max_beams );
|
||||
CL_ClearViewBeams();
|
||||
}
|
||||
|
||||
|
@ -1381,7 +1371,7 @@ void CL_AddCustomBeam( cl_entity_t *pEnvBeam )
|
|||
{
|
||||
if( tr.draw_list->num_beam_entities >= MAX_VISIBLE_PACKET )
|
||||
{
|
||||
MsgDev( D_ERROR, "Too many custom beams %d!\n", tr.draw_list->num_beam_entities );
|
||||
Con_Printf( S_ERROR "Too many beams %d!\n", tr.draw_list->num_beam_entities );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1496,7 +1486,7 @@ void CL_DrawBeams( int fTrans )
|
|||
BEAM *pPrev = NULL;
|
||||
int i, flags;
|
||||
|
||||
if( !cl_draw_beams->value )
|
||||
if( !CVAR_TO_BOOL( cl_draw_beams ))
|
||||
return;
|
||||
|
||||
pglShadeModel( GL_SMOOTH );
|
||||
|
@ -1875,7 +1865,6 @@ void CL_ParseViewBeam( sizebuf_t *msg, int beamType )
|
|||
R_BeamEnts( startEnt, endEnt, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
|
||||
break;
|
||||
case TE_BEAM:
|
||||
MsgDev( D_ERROR, "TE_BEAM is obsolete\n" );
|
||||
break;
|
||||
case TE_BEAMSPRITE:
|
||||
start[0] = MSG_ReadCoord( msg );
|
||||
|
@ -1901,14 +1890,14 @@ void CL_ParseViewBeam( sizebuf_t *msg, int beamType )
|
|||
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);
|
||||
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 );
|
||||
R_BeamCirclePoints( beamType, start, end, modelIndex, life, width, noise, a, speed / 10.0f, startFrame, frameRate, r, g, b );
|
||||
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 );
|
||||
|
@ -1938,7 +1927,6 @@ void CL_ParseViewBeam( sizebuf_t *msg, int beamType )
|
|||
R_BeamRing( startEnt, endEnt, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
|
||||
break;
|
||||
case TE_BEAMHOSE:
|
||||
MsgDev( D_ERROR, "TE_BEAMHOSE is obsolete\n" );
|
||||
break;
|
||||
case TE_KILLBEAM:
|
||||
startEnt = MSG_ReadShort( msg );
|
||||
|
@ -2015,7 +2003,7 @@ void CL_ReadLineFile_f( void )
|
|||
|
||||
count++;
|
||||
|
||||
if( !R_BeamPoints( p1, p2, modelIndex, 99999, 2, 0, 255, 0, 0, 0, 255.0f, 0.0f, 0.0f ))
|
||||
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 );
|
||||
|
|
|
@ -524,7 +524,7 @@ glpoly_t *R_DecalCreatePoly( decalinfo_t *decalinfo, decal_t *pdecal, msurface_t
|
|||
if( !lnumverts ) return NULL; // probably this never happens
|
||||
|
||||
// allocate glpoly
|
||||
poly = Mem_Alloc( com_studiocache, sizeof( glpoly_t ) + ( lnumverts - 4 ) * VERTEXSIZE * sizeof( float ));
|
||||
poly = Mem_Calloc( com_studiocache, sizeof( glpoly_t ) + ( lnumverts - 4 ) * VERTEXSIZE * sizeof( float ));
|
||||
poly->next = pdecal->polys;
|
||||
poly->flags = surf->flags;
|
||||
pdecal->polys = poly;
|
||||
|
@ -577,11 +577,7 @@ static void R_DecalCreate( decalinfo_t *decalinfo, msurface_t *surf, float x, fl
|
|||
decal_t *pdecal, *pold;
|
||||
int count, vertCount;
|
||||
|
||||
if( !surf )
|
||||
{
|
||||
MsgDev( D_ERROR, "psurface NULL in R_DecalCreate!\n" );
|
||||
return;
|
||||
}
|
||||
if( !surf ) return; // ???
|
||||
|
||||
pold = R_DecalIntersect( decalinfo, surf, &count );
|
||||
if( count < MAX_OVERLAP_DECALS ) pold = NULL;
|
||||
|
@ -763,7 +759,7 @@ void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos
|
|||
|
||||
if( textureIndex <= 0 || textureIndex >= MAX_TEXTURES )
|
||||
{
|
||||
MsgDev( D_ERROR, "Decal has invalid texture!\n" );
|
||||
Con_Printf( S_ERROR "Decal has invalid texture!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -783,7 +779,7 @@ void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos
|
|||
|
||||
if( model->type != mod_brush )
|
||||
{
|
||||
MsgDev( D_ERROR, "Decals must hit mod_brush!\n" );
|
||||
Con_Printf( S_ERROR "Decals must hit mod_brush!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -988,7 +984,6 @@ void DrawSurfaceDecals( msurface_t *fa, qboolean single, qboolean reverse )
|
|||
}
|
||||
}
|
||||
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
|
||||
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
if( reverse && e->curstate.rendermode == kRenderTransTexture )
|
||||
|
@ -1224,10 +1219,7 @@ void R_DecalRemoveAll( int textureIndex )
|
|||
int i;
|
||||
|
||||
if( textureIndex < 0 || textureIndex >= MAX_TEXTURES )
|
||||
{
|
||||
MsgDev( D_ERROR, "Decal has invalid texture!\n" );
|
||||
return;
|
||||
}
|
||||
return; // out of bounds
|
||||
|
||||
for( i = 0; i < gDecalCount; i++ )
|
||||
{
|
||||
|
|
|
@ -24,7 +24,7 @@ R_GetImageParms
|
|||
*/
|
||||
void R_GetTextureParms( int *w, int *h, int texnum )
|
||||
{
|
||||
gltexture_t *glt;
|
||||
gl_texture_t *glt;
|
||||
|
||||
glt = R_GetTexture( texnum );
|
||||
if( w ) *w = glt->srcWidth;
|
||||
|
@ -94,7 +94,7 @@ refresh window.
|
|||
void R_DrawTileClear( int x, int y, int w, int h )
|
||||
{
|
||||
float tw, th;
|
||||
gltexture_t *glt;
|
||||
gl_texture_t *glt;
|
||||
|
||||
GL_SetRenderMode( kRenderNormal );
|
||||
pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
|
@ -124,7 +124,7 @@ R_DrawStretchRaw
|
|||
void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty )
|
||||
{
|
||||
byte *raw = NULL;
|
||||
gltexture_t *tex;
|
||||
gl_texture_t *tex;
|
||||
|
||||
if( !GL_Support( GL_ARB_TEXTURE_NPOT_EXT ))
|
||||
{
|
||||
|
@ -196,7 +196,7 @@ R_UploadStretchRaw
|
|||
void R_UploadStretchRaw( int texture, int cols, int rows, int width, int height, const byte *data )
|
||||
{
|
||||
byte *raw = NULL;
|
||||
gltexture_t *tex;
|
||||
gl_texture_t *tex;
|
||||
|
||||
if( !GL_Support( GL_ARB_TEXTURE_NPOT_EXT ))
|
||||
{
|
||||
|
|
|
@ -148,6 +148,7 @@ typedef float GLmatrix[16];
|
|||
#define GL_2_BYTES 0x1407
|
||||
#define GL_3_BYTES 0x1408
|
||||
#define GL_4_BYTES 0x1409
|
||||
#define GL_HALF_FLOAT_ARB 0x140B
|
||||
|
||||
#define GL_VERTEX_ARRAY 0x8074
|
||||
#define GL_NORMAL_ARRAY 0x8075
|
||||
|
@ -390,6 +391,7 @@ typedef float GLmatrix[16];
|
|||
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
|
||||
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
|
||||
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
|
||||
#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
|
||||
#define GL_COMPRESSED_ALPHA_ARB 0x84E9
|
||||
#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA
|
||||
#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -38,6 +38,7 @@ extern byte *r_temppool;
|
|||
|
||||
#define SHADEDOT_QUANT 16 // precalculated dot products for quantized angles
|
||||
#define SHADE_LAMBERT 1.495f
|
||||
#define DEFAULT_ALPHATEST 0.0f
|
||||
|
||||
// refparams
|
||||
#define RP_NONE 0
|
||||
|
@ -92,7 +93,7 @@ typedef struct gltexture_s
|
|||
int servercount;
|
||||
uint hashValue;
|
||||
struct gltexture_s *nextHash;
|
||||
} gltexture_t;
|
||||
} gl_texture_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -201,6 +202,10 @@ typedef struct
|
|||
qboolean fResetVis;
|
||||
qboolean fFlipViewModel;
|
||||
|
||||
// tree visualization stuff
|
||||
int recursion_level;
|
||||
int max_recursion;
|
||||
|
||||
byte visbytes[(MAX_MAP_LEAFS+7)/8]; // member custom PVS
|
||||
int lightstylevalue[MAX_LIGHTSTYLES]; // value 0 - 65536
|
||||
int block_size; // lightmap blocksize
|
||||
|
@ -228,6 +233,8 @@ typedef struct
|
|||
uint c_particle_count;
|
||||
|
||||
uint c_client_ents; // entities that moved to client
|
||||
double t_world_node;
|
||||
double t_world_draw;
|
||||
} ref_speeds_t;
|
||||
|
||||
extern ref_speeds_t r_stats;
|
||||
|
@ -235,8 +242,6 @@ extern ref_instance_t RI;
|
|||
extern ref_globals_t tr;
|
||||
|
||||
extern float gldepthmin, gldepthmax;
|
||||
extern mleaf_t *r_viewleaf, *r_oldviewleaf;
|
||||
extern mleaf_t *r_viewleaf2, *r_oldviewleaf2;
|
||||
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)
|
||||
|
@ -267,6 +272,7 @@ void GL_SetRenderMode( int mode );
|
|||
void GL_TextureTarget( uint target );
|
||||
void GL_Cull( GLenum cull );
|
||||
void R_ShowTextures( void );
|
||||
void R_ShowTree( void );
|
||||
|
||||
//
|
||||
// gl_cull.c
|
||||
|
@ -293,20 +299,28 @@ void R_Set2DMode( qboolean enable );
|
|||
void R_DrawTileClear( int x, int y, int w, int h );
|
||||
void R_UploadStretchRaw( int texture, int cols, int rows, int width, int height, const byte *data );
|
||||
|
||||
//
|
||||
// gl_drawhulls.c
|
||||
//
|
||||
void R_DrawWorldHull( void );
|
||||
void R_DrawModelHull( void );
|
||||
|
||||
//
|
||||
// gl_image.c
|
||||
//
|
||||
void R_SetTextureParameters( void );
|
||||
gltexture_t *R_GetTexture( GLenum texnum );
|
||||
int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags, imgfilter_t *filter );
|
||||
int GL_LoadTextureArray( const char **names, int flags, imgfilter_t *filter );
|
||||
int GL_LoadTextureInternal( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update );
|
||||
gl_texture_t *R_GetTexture( GLenum texnum );
|
||||
#define GL_LoadTextureInternal( name, pic, flags ) GL_LoadTextureFromBuffer( name, pic, flags, false )
|
||||
#define GL_UpdateTextureInternal( name, pic, flags ) GL_LoadTextureFromBuffer( name, pic, flags, true )
|
||||
int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags );
|
||||
int GL_LoadTextureArray( const char **names, int flags );
|
||||
int GL_LoadTextureFromBuffer( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update );
|
||||
byte *GL_ResampleTexture( const byte *source, int in_w, int in_h, int out_w, int out_h, qboolean isNormalMap );
|
||||
int GL_CreateTexture( const char *name, int width, int height, const void *buffer, texFlags_t flags );
|
||||
int GL_CreateTextureArray( const char *name, int width, int height, int depth, const void *buffer, texFlags_t flags );
|
||||
void GL_ProcessTexture( int texnum, float gamma, int topColor, int bottomColor );
|
||||
void GL_ApplyTextureParams( gltexture_t *tex );
|
||||
void R_FreeImage( gltexture_t *image );
|
||||
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 );
|
||||
|
@ -328,8 +342,7 @@ void R_PushDlights( void );
|
|||
void R_AnimateLight( void );
|
||||
void R_GetLightSpot( vec3_t lightspot );
|
||||
void R_MarkLights( dlight_t *light, int bit, mnode_t *node );
|
||||
void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLight, qboolean useAmbient, float radius );
|
||||
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lightspot );
|
||||
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lightspot, vec3_t lightvec );
|
||||
int R_CountSurfaceDlights( msurface_t *surf );
|
||||
colorVec R_LightPoint( const vec3_t p0 );
|
||||
int R_CountDlights( void );
|
||||
|
@ -376,8 +389,7 @@ void Matrix4x4_CreateModelview( matrix4x4 out );
|
|||
//
|
||||
// gl_rmisc.
|
||||
//
|
||||
void R_ParseTexFilters( const char *filename );
|
||||
imgfilter_t *R_FindTexFilter( const char *texname );
|
||||
void R_ClearStaticEntities( void );
|
||||
|
||||
//
|
||||
// gl_rsurf.c
|
||||
|
@ -417,6 +429,7 @@ float CL_GetStudioEstimatedFrame( cl_entity_t *ent );
|
|||
int R_GetEntityRenderMode( cl_entity_t *ent );
|
||||
void R_DrawStudioModel( cl_entity_t *e );
|
||||
player_info_t *pfnPlayerInfo( int index );
|
||||
void R_GatherPlayerLight( void );
|
||||
|
||||
//
|
||||
// gl_alias.c
|
||||
|
@ -444,7 +457,7 @@ void EmitWaterPolys( msurface_t *warp, qboolean reverse );
|
|||
qboolean R_Init( void );
|
||||
void R_Shutdown( void );
|
||||
void VID_CheckChanges( void );
|
||||
int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags, imgfilter_t *filter );
|
||||
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 );
|
||||
|
@ -508,7 +521,6 @@ enum
|
|||
GL_ARB_DEPTH_FLOAT_EXT,
|
||||
GL_ARB_SEAMLESS_CUBEMAP,
|
||||
GL_EXT_GPU_SHADER4, // shaders only
|
||||
GL_ARB_TEXTURE_RG,
|
||||
GL_DEPTH_TEXTURE,
|
||||
GL_DEBUG_OUTPUT,
|
||||
GL_EXTCOUNT, // must be last
|
||||
|
@ -597,17 +609,20 @@ typedef struct
|
|||
|
||||
typedef enum
|
||||
{
|
||||
SAFE_NO,
|
||||
SAFE_NOACC,
|
||||
SAFE_NODEPTH,
|
||||
SAFE_NOATTRIB,
|
||||
SAFE_DONTCARE
|
||||
SAFE_NO = 0,
|
||||
SAFE_NOMSAA, // skip msaa
|
||||
SAFE_NOACC, // don't set acceleration flag
|
||||
SAFE_NOSTENCIL, // don't set stencil bits
|
||||
SAFE_NOALPHA, // don't set alpha bits
|
||||
SAFE_NODEPTH, // don't set depth bits
|
||||
SAFE_NOCOLOR, // don't set color bits
|
||||
SAFE_DONTCARE // ignore everything, let SDL/EGL decide
|
||||
} safe_context_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void* context; // handle to GL rendering context
|
||||
safe_context_t safe;
|
||||
int safe;
|
||||
|
||||
int desktopBitsPixel;
|
||||
int desktopWidth;
|
||||
|
@ -629,8 +644,10 @@ 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;
|
||||
|
@ -642,10 +659,10 @@ extern convar_t *gl_test; // cvar to testify new effects
|
|||
extern convar_t *gl_msaa;
|
||||
extern convar_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;
|
||||
|
|
|
@ -81,7 +81,6 @@ R_SplitEntityOnNode
|
|||
static void R_SplitEntityOnNode( mnode_t *node )
|
||||
{
|
||||
efrag_t *ef;
|
||||
mplane_t *splitplane;
|
||||
mleaf_t *leaf;
|
||||
int sides;
|
||||
|
||||
|
@ -100,7 +99,7 @@ static void R_SplitEntityOnNode( mnode_t *node )
|
|||
ef = clgame.free_efrags;
|
||||
if( !ef )
|
||||
{
|
||||
MsgDev( D_ERROR, "too many efrags!\n" );
|
||||
Con_Printf( S_ERROR "too many efrags!\n" );
|
||||
return; // no free fragments...
|
||||
}
|
||||
|
||||
|
@ -120,8 +119,7 @@ static void R_SplitEntityOnNode( mnode_t *node )
|
|||
}
|
||||
|
||||
// NODE_MIXED
|
||||
splitplane = node->plane;
|
||||
sides = BOX_ON_PLANE_SIDE( r_emins, r_emaxs, splitplane );
|
||||
sides = BOX_ON_PLANE_SIDE( r_emins, r_emaxs, node->plane );
|
||||
|
||||
if( sides == 3 )
|
||||
{
|
||||
|
@ -142,6 +140,8 @@ R_AddEfrags
|
|||
*/
|
||||
void R_AddEfrags( cl_entity_t *ent )
|
||||
{
|
||||
matrix3x4 transform;
|
||||
vec3_t outmins, outmaxs;
|
||||
int i;
|
||||
|
||||
if( !ent->model )
|
||||
|
@ -151,10 +151,14 @@ void R_AddEfrags( cl_entity_t *ent )
|
|||
lastlink = &ent->efrag;
|
||||
r_pefragtopnode = NULL;
|
||||
|
||||
// handle entity rotation for right bbox expanding
|
||||
Matrix3x4_CreateFromEntity( transform, ent->angles, vec3_origin, 1.0f );
|
||||
Matrix3x4_TransformAABB( transform, ent->model->mins, ent->model->maxs, outmins, outmaxs );
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
r_emins[i] = ent->origin[i] + ent->model->mins[i];
|
||||
r_emaxs[i] = ent->origin[i] + ent->model->maxs[i];
|
||||
r_emins[i] = ent->origin[i] + outmins[i];
|
||||
r_emaxs[i] = ent->origin[i] + outmaxs[i];
|
||||
}
|
||||
|
||||
R_SplitEntityOnNode( cl.worldmodel->nodes );
|
||||
|
@ -191,6 +195,7 @@ void R_StoreEfrags( efrag_t **ppefrag, int framecount )
|
|||
if( CL_AddVisibleEntity( pent, ET_FRAGMENTED ))
|
||||
{
|
||||
// mark that we've recorded this entity for this frame
|
||||
pent->curstate.messagenum = cl.parsecount;
|
||||
pent->visframe = framecount;
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +203,6 @@ void R_StoreEfrags( efrag_t **ppefrag, int framecount )
|
|||
ppefrag = &pefrag->leafnext;
|
||||
break;
|
||||
default:
|
||||
Host_Error( "R_StoreEfrags: bad entity type %d\n", clmodel->type );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ void CL_RunLightStyles( void )
|
|||
// 'm' is normal light, 'a' is no light, 'z' is double bright
|
||||
for( i = 0, ls = cl.lightstyles; i < MAX_LIGHTSTYLES; i++, ls++ )
|
||||
{
|
||||
if( r_fullbright->value || !cl.worldmodel->lightdata )
|
||||
if( !cl.worldmodel->lightdata )
|
||||
{
|
||||
tr.lightstylevalue[i] = 256 * 256;
|
||||
continue;
|
||||
|
@ -74,7 +74,7 @@ void CL_RunLightStyles( void )
|
|||
tr.lightstylevalue[i] = ls->map[0] * 22 * scale;
|
||||
continue;
|
||||
}
|
||||
else if( !ls->interp || !cl_lightstyle_lerping->value )
|
||||
else if( !ls->interp || !CVAR_TO_BOOL( cl_lightstyle_lerping ))
|
||||
{
|
||||
tr.lightstylevalue[i] = ls->map[flight%ls->length] * 22 * scale;
|
||||
continue;
|
||||
|
@ -104,7 +104,7 @@ void R_MarkLights( dlight_t *light, int bit, mnode_t *node )
|
|||
msurface_t *surf;
|
||||
int i;
|
||||
|
||||
if( node->contents < 0 )
|
||||
if( !node || node->contents < 0 )
|
||||
return;
|
||||
|
||||
dist = PlaneDiff( light->origin, node->plane );
|
||||
|
@ -217,6 +217,7 @@ int R_CountSurfaceDlights( msurface_t *surf )
|
|||
=======================================================================
|
||||
*/
|
||||
static vec3_t g_trace_lightspot;
|
||||
static vec3_t g_trace_lightvec;
|
||||
static float g_trace_fraction;
|
||||
|
||||
/*
|
||||
|
@ -230,10 +231,11 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
|
|||
int i, map, side, size;
|
||||
float ds, dt, s, t;
|
||||
int sample_size;
|
||||
color24 *lm, *dm;
|
||||
mextrasurf_t *info;
|
||||
msurface_t *surf;
|
||||
mtexinfo_t *tex;
|
||||
color24 *lm;
|
||||
matrix3x4 tbn;
|
||||
vec3_t mid;
|
||||
|
||||
// didn't hit anything
|
||||
|
@ -306,6 +308,31 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
|
|||
lm = surf->samples + Q_rint( dt ) * smax + Q_rint( ds );
|
||||
g_trace_fraction = midf;
|
||||
size = smax * tmax;
|
||||
dm = NULL;
|
||||
|
||||
if( surf->info->deluxemap )
|
||||
{
|
||||
vec3_t faceNormal;
|
||||
|
||||
if( FBitSet( surf->flags, SURF_PLANEBACK ))
|
||||
VectorNegate( surf->plane->normal, faceNormal );
|
||||
else VectorCopy( surf->plane->normal, faceNormal );
|
||||
|
||||
// compute face TBN
|
||||
#if 1
|
||||
Vector4Set( tbn[0], surf->info->lmvecs[0][0], surf->info->lmvecs[0][1], surf->info->lmvecs[0][2], 0.0f );
|
||||
Vector4Set( tbn[1], -surf->info->lmvecs[1][0], -surf->info->lmvecs[1][1], -surf->info->lmvecs[1][2], 0.0f );
|
||||
Vector4Set( tbn[2], faceNormal[0], faceNormal[1], faceNormal[2], 0.0f );
|
||||
#else
|
||||
Vector4Set( tbn[0], surf->info->lmvecs[0][0], -surf->info->lmvecs[1][0], faceNormal[0], 0.0f );
|
||||
Vector4Set( tbn[1], surf->info->lmvecs[0][1], -surf->info->lmvecs[1][1], faceNormal[1], 0.0f );
|
||||
Vector4Set( tbn[2], surf->info->lmvecs[0][2], -surf->info->lmvecs[1][2], faceNormal[2], 0.0f );
|
||||
#endif
|
||||
VectorNormalize( tbn[0] );
|
||||
VectorNormalize( tbn[1] );
|
||||
VectorNormalize( tbn[2] );
|
||||
dm = surf->info->deluxemap + Q_rint( dt ) * smax + Q_rint( ds );
|
||||
}
|
||||
|
||||
for( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ )
|
||||
{
|
||||
|
@ -324,6 +351,18 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
|
|||
cv->b += LightToTexGamma( lm->b ) * scale;
|
||||
}
|
||||
lm += size; // skip to next lightmap
|
||||
|
||||
if( dm != NULL )
|
||||
{
|
||||
vec3_t srcNormal, lightNormal;
|
||||
float f = (1.0f / 128.0f);
|
||||
|
||||
VectorSet( srcNormal, ((float)dm->r - 128.0f) * f, ((float)dm->g - 128.0f) * f, ((float)dm->b - 128.0f) * f );
|
||||
Matrix3x4_VectorIRotate( tbn, srcNormal, lightNormal ); // turn to world space
|
||||
VectorScale( lightNormal, (float)scale * -1.0f, lightNormal ); // turn direction from light
|
||||
VectorAdd( g_trace_lightvec, lightNormal, g_trace_lightvec );
|
||||
dm += size; // skip to next deluxmap
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -340,13 +379,14 @@ R_LightVec
|
|||
check bspmodels to get light from
|
||||
=================
|
||||
*/
|
||||
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot )
|
||||
colorVec R_LightVecInternal( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec )
|
||||
{
|
||||
float last_fraction;
|
||||
int i, maxEnts = 1;
|
||||
colorVec light, cv;
|
||||
|
||||
if( lspot ) VectorClear( lspot );
|
||||
if( lvec ) VectorClear( lvec );
|
||||
|
||||
if( cl.worldmodel && cl.worldmodel->lightdata )
|
||||
{
|
||||
|
@ -354,7 +394,7 @@ colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot )
|
|||
last_fraction = 1.0f;
|
||||
|
||||
// get light from bmodels too
|
||||
if( r_lighting_extended->value )
|
||||
if( CVAR_TO_BOOL( r_lighting_extended ))
|
||||
maxEnts = clgame.pmove->numphysent;
|
||||
|
||||
// check all the bsp-models
|
||||
|
@ -383,6 +423,7 @@ colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot )
|
|||
}
|
||||
|
||||
VectorClear( g_trace_lightspot );
|
||||
VectorClear( g_trace_lightvec );
|
||||
g_trace_fraction = 1.0f;
|
||||
|
||||
if( !R_RecursiveLightPoint( pe->model, pnodes, 0.0f, 1.0f, &cv, start_l, end_l ))
|
||||
|
@ -391,10 +432,14 @@ colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot )
|
|||
if( g_trace_fraction < last_fraction )
|
||||
{
|
||||
if( lspot ) VectorCopy( g_trace_lightspot, lspot );
|
||||
if( lvec ) VectorNormalize2( g_trace_lightvec, lvec );
|
||||
light.r = Q_min(( cv.r >> 7 ), 255 );
|
||||
light.g = Q_min(( cv.g >> 7 ), 255 );
|
||||
light.b = Q_min(( cv.b >> 7 ), 255 );
|
||||
last_fraction = g_trace_fraction;
|
||||
|
||||
if(( light.r + light.g + light.b ) != 0 )
|
||||
break; // we get light now
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -407,6 +452,27 @@ colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot )
|
|||
return light;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_LightVec
|
||||
|
||||
check bspmodels to get light from
|
||||
=================
|
||||
*/
|
||||
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec )
|
||||
{
|
||||
colorVec light = R_LightVecInternal( start, end, lspot, lvec );
|
||||
|
||||
if( CVAR_TO_BOOL( r_lighting_extended ) && lspot != NULL && lvec != NULL )
|
||||
{
|
||||
// trying to get light from ceiling (but ignore gradient analyze)
|
||||
if(( light.r + light.g + light.b ) == 0 )
|
||||
return R_LightVecInternal( end, start, lspot, lvec );
|
||||
}
|
||||
|
||||
return light;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_LightPoint
|
||||
|
@ -420,5 +486,5 @@ colorVec R_LightPoint( const vec3_t p0 )
|
|||
|
||||
VectorSet( p1, p0[0], p0[1], p0[2] - 2048.0f );
|
||||
|
||||
return R_LightVec( p0, p1, NULL );
|
||||
return R_LightVec( p0, p1, NULL, NULL );
|
||||
}
|
|
@ -21,11 +21,10 @@ GNU General Public License for more details.
|
|||
#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 )
|
||||
|
||||
msurface_t *r_debug_surface;
|
||||
const char *r_debug_hitbox;
|
||||
float gldepthmin, gldepthmax;
|
||||
ref_instance_t RI;
|
||||
|
||||
|
@ -207,7 +206,7 @@ void R_PushScene( void )
|
|||
|
||||
/*
|
||||
===============
|
||||
R_PushScene
|
||||
R_PopScene
|
||||
===============
|
||||
*/
|
||||
void R_PopScene( void )
|
||||
|
@ -242,10 +241,10 @@ qboolean R_AddEntity( struct cl_entity_s *clent, int type )
|
|||
if( !clent || !clent->model )
|
||||
return false; // if set to invisible, skip
|
||||
|
||||
if( clent->curstate.effects & EF_NODRAW )
|
||||
if( FBitSet( clent->curstate.effects, EF_NODRAW ))
|
||||
return false; // done
|
||||
|
||||
if( clent->curstate.rendermode != kRenderNormal && CL_FxBlend( clent ) <= 0 )
|
||||
if( !R_ModelOpaque( clent->curstate.rendermode ) && CL_FxBlend( clent ) <= 0 )
|
||||
return true; // invisible
|
||||
|
||||
if( type == ET_FRAGMENTED )
|
||||
|
@ -541,7 +540,7 @@ void R_SetupGL( qboolean set_gl_state )
|
|||
pglMatrixMode( GL_MODELVIEW );
|
||||
GL_LoadMatrix( RI.worldviewMatrix );
|
||||
|
||||
if( RI.params & RP_CLIPPLANE )
|
||||
if( FBitSet( RI.params, RP_CLIPPLANE ))
|
||||
{
|
||||
GLdouble clip[4];
|
||||
mplane_t *p = &RI.clipPlane;
|
||||
|
@ -581,9 +580,9 @@ using to find source waterleaf with
|
|||
watertexture to grab fog values from it
|
||||
=============
|
||||
*/
|
||||
static gltexture_t *R_RecursiveFindWaterTexture( const mnode_t *node, const mnode_t *ignore, qboolean down )
|
||||
static gl_texture_t *R_RecursiveFindWaterTexture( const mnode_t *node, const mnode_t *ignore, qboolean down )
|
||||
{
|
||||
gltexture_t *tex = NULL;
|
||||
gl_texture_t *tex = NULL;
|
||||
|
||||
// assure the initial node is not null
|
||||
// we could check it here, but we would rather check it
|
||||
|
@ -656,17 +655,25 @@ from underwater leaf (idea: XaeroX)
|
|||
static void R_CheckFog( void )
|
||||
{
|
||||
cl_entity_t *ent;
|
||||
gltexture_t *tex;
|
||||
gl_texture_t *tex;
|
||||
int i, cnt, count;
|
||||
|
||||
// quake global fog
|
||||
if( clgame.movevars.fog_settings != 0 && FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
if( Host_IsQuakeCompatible( ))
|
||||
{
|
||||
if( !clgame.movevars.fog_settings )
|
||||
{
|
||||
if( pglIsEnabled( GL_FOG ))
|
||||
pglDisable( GL_FOG );
|
||||
RI.fogEnabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 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.015625f;
|
||||
RI.fogDensity = ((clgame.movevars.fog_settings & 0xFF) / 255.0f) * 0.01f;
|
||||
RI.fogStart = RI.fogEnd = 0.0f;
|
||||
RI.fogColor[3] = 1.0f;
|
||||
RI.fogCustom = false;
|
||||
|
@ -675,15 +682,6 @@ static void R_CheckFog( void )
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
// special condition for Spirit 1.9 that used direct calls of glFog-functions
|
||||
if(( !RI.fogEnabled && !RI.fogCustom ) && pglIsEnabled( GL_FOG ) && VectorIsNull( RI.fogColor ))
|
||||
{
|
||||
// fill the fog color from GL-state machine
|
||||
pglGetFloatv( GL_FOG_COLOR, RI.fogColor );
|
||||
RI.fogSkybox = true;
|
||||
}
|
||||
#endif
|
||||
RI.fogEnabled = false;
|
||||
|
||||
if( RI.onlyClientDraw || cl.local.waterlevel < 3 || !RI.drawWorld || !RI.viewleaf )
|
||||
|
@ -753,6 +751,26 @@ static void R_CheckFog( void )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_CheckGLFog
|
||||
|
||||
special condition for Spirit 1.9
|
||||
that used direct calls of glFog-functions
|
||||
=============
|
||||
*/
|
||||
static void R_CheckGLFog( void )
|
||||
{
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
if(( !RI.fogEnabled && !RI.fogCustom ) && pglIsEnabled( GL_FOG ) && VectorIsNull( RI.fogColor ))
|
||||
{
|
||||
// fill the fog color from GL-state machine
|
||||
pglGetFloatv( GL_FOG_COLOR, RI.fogColor );
|
||||
RI.fogSkybox = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_DrawFog
|
||||
|
@ -764,7 +782,9 @@ void R_DrawFog( void )
|
|||
if( !RI.fogEnabled ) return;
|
||||
|
||||
pglEnable( GL_FOG );
|
||||
pglFogi( GL_FOG_MODE, GL_EXP );
|
||||
if( Host_IsQuakeCompatible( ))
|
||||
pglFogi( GL_FOG_MODE, GL_EXP2 );
|
||||
else pglFogi( GL_FOG_MODE, GL_EXP );
|
||||
pglFogf( GL_FOG_DENSITY, RI.fogDensity );
|
||||
pglFogfv( GL_FOG_COLOR, RI.fogColor );
|
||||
pglHint( GL_FOG_HINT, GL_NICEST );
|
||||
|
@ -940,6 +960,7 @@ void R_RenderScene( void )
|
|||
R_MarkLeaves();
|
||||
R_DrawFog ();
|
||||
|
||||
R_CheckGLFog();
|
||||
R_DrawWorld();
|
||||
R_CheckFog();
|
||||
|
||||
|
@ -977,7 +998,6 @@ qboolean R_DoResetGamma( void )
|
|||
return false;
|
||||
case scrshot_plaque:
|
||||
case scrshot_savegame:
|
||||
case scrshot_demoshot:
|
||||
case scrshot_envshot:
|
||||
case scrshot_skyshot:
|
||||
case scrshot_mapshot:
|
||||
|
@ -1084,8 +1104,13 @@ void R_RenderFrame( const ref_viewpass_t *rvp )
|
|||
if( gl_finish->value && RI.drawWorld )
|
||||
pglFinish();
|
||||
|
||||
if( glConfig.max_multisamples > 1 )
|
||||
if( glConfig.max_multisamples > 1 && FBitSet( gl_msaa->flags, FCVAR_CHANGED ))
|
||||
{
|
||||
if( CVAR_TO_BOOL( gl_msaa ))
|
||||
pglEnable( GL_MULTISAMPLE_ARB );
|
||||
else pglDisable( GL_MULTISAMPLE_ARB );
|
||||
ClearBits( gl_msaa->flags, FCVAR_CHANGED );
|
||||
}
|
||||
|
||||
// completely override rendering
|
||||
if( clgame.drawFuncs.GL_RenderFrame != NULL )
|
||||
|
@ -1094,6 +1119,7 @@ void R_RenderFrame( const ref_viewpass_t *rvp )
|
|||
|
||||
if( clgame.drawFuncs.GL_RenderFrame( rvp ))
|
||||
{
|
||||
R_GatherPlayerLight();
|
||||
tr.realframecount++;
|
||||
tr.fResetVis = true;
|
||||
return;
|
||||
|
@ -1154,7 +1180,7 @@ void R_DrawCubemapView( const vec3_t origin, const vec3_t angles, int size )
|
|||
|
||||
static int GL_RenderGetParm( int parm, int arg )
|
||||
{
|
||||
gltexture_t *glt;
|
||||
gl_texture_t *glt;
|
||||
|
||||
switch( parm )
|
||||
{
|
||||
|
@ -1197,6 +1223,8 @@ static int GL_RenderGetParm( int parm, int arg )
|
|||
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:
|
||||
|
@ -1253,7 +1281,7 @@ static int GL_RenderGetParm( int parm, int arg )
|
|||
|
||||
static void R_GetDetailScaleForTexture( int texture, float *xScale, float *yScale )
|
||||
{
|
||||
gltexture_t *glt = R_GetTexture( texture );
|
||||
gl_texture_t *glt = R_GetTexture( texture );
|
||||
|
||||
if( xScale ) *xScale = glt->xscale;
|
||||
if( yScale ) *yScale = glt->yscale;
|
||||
|
@ -1261,7 +1289,7 @@ static void R_GetDetailScaleForTexture( int texture, float *xScale, float *yScal
|
|||
|
||||
static void R_GetExtraParmsForTexture( int texture, byte *red, byte *green, byte *blue, byte *density )
|
||||
{
|
||||
gltexture_t *glt = R_GetTexture( texture );
|
||||
gl_texture_t *glt = R_GetTexture( texture );
|
||||
|
||||
if( red ) *red = glt->fogParams[0];
|
||||
if( green ) *green = glt->fogParams[1];
|
||||
|
@ -1279,16 +1307,13 @@ static void R_EnvShot( const float *vieworg, const char *name, qboolean skyshot,
|
|||
{
|
||||
static vec3_t viewPoint;
|
||||
|
||||
if( !name )
|
||||
{
|
||||
MsgDev( D_ERROR, "R_%sShot: bad name\n", skyshot ? "Sky" : "Env" );
|
||||
if( !COM_CheckString( name ))
|
||||
return;
|
||||
}
|
||||
|
||||
if( cls.scrshot_action != scrshot_inactive )
|
||||
{
|
||||
if( cls.scrshot_action != scrshot_skyshot && cls.scrshot_action != scrshot_envshot )
|
||||
MsgDev( D_ERROR, "R_%sShot: subsystem is busy, try later.\n", skyshot ? "Sky" : "Env" );
|
||||
Con_Printf( S_ERROR "R_%sShot: subsystem is busy, try for next frame.\n", skyshot ? "Sky" : "Env" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1369,16 +1394,6 @@ const byte *GL_TextureData( unsigned int texnum )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int GL_LoadTextureNoFilter( const char *name, const byte *buf, size_t size, int flags )
|
||||
{
|
||||
return GL_LoadTexture( name, buf, size, flags, NULL );
|
||||
}
|
||||
|
||||
static int GL_LoadTextureArrayNoFilter( const char **names, int flags )
|
||||
{
|
||||
return GL_LoadTextureArray( names, flags, NULL );
|
||||
}
|
||||
|
||||
static const ref_overview_t *GL_GetOverviewParms( void )
|
||||
{
|
||||
return &clgame.overView;
|
||||
|
@ -1386,7 +1401,7 @@ static const ref_overview_t *GL_GetOverviewParms( void )
|
|||
|
||||
static void *R_Mem_Alloc( size_t cb, const char *filename, const int fileline )
|
||||
{
|
||||
return _Mem_Alloc( cls.mempool, cb, filename, fileline );
|
||||
return _Mem_Alloc( cls.mempool, cb, true, filename, fileline );
|
||||
}
|
||||
|
||||
static void R_Mem_Free( void *mem, const char *filename, const int fileline )
|
||||
|
@ -1461,22 +1476,22 @@ static render_api_t gRenderAPI =
|
|||
GL_FindTexture,
|
||||
GL_TextureName,
|
||||
GL_TextureData,
|
||||
GL_LoadTextureNoFilter,
|
||||
GL_LoadTexture,
|
||||
GL_CreateTexture,
|
||||
GL_LoadTextureArrayNoFilter,
|
||||
GL_LoadTextureArray,
|
||||
GL_CreateTextureArray,
|
||||
GL_FreeTexture,
|
||||
DrawSingleDecal,
|
||||
R_DecalSetupVerts,
|
||||
R_EntityRemoveDecals,
|
||||
(void*)AVI_LoadVideoNoSound,
|
||||
(void*)AVI_LoadVideo,
|
||||
(void*)AVI_GetVideoInfo,
|
||||
(void*)AVI_GetVideoFrameNumber,
|
||||
(void*)AVI_GetVideoFrame,
|
||||
R_UploadStretchRaw,
|
||||
(void*)AVI_FreeVideo,
|
||||
(void*)AVI_IsActive,
|
||||
NULL,
|
||||
S_StreamAviSamples,
|
||||
NULL,
|
||||
NULL,
|
||||
GL_Bind,
|
||||
|
@ -1488,7 +1503,7 @@ static render_api_t gRenderAPI =
|
|||
GL_TextureTarget,
|
||||
GL_SetTexCoordArrayMode,
|
||||
GL_GetProcAddress,
|
||||
NULL,
|
||||
GL_UpdateTexSize,
|
||||
NULL,
|
||||
NULL,
|
||||
CL_DrawParticlesExternal,
|
||||
|
@ -1529,7 +1544,7 @@ qboolean R_InitRenderAPI( void )
|
|||
{
|
||||
if( clgame.dllFuncs.pfnGetRenderInterface( CL_RENDER_INTERFACE_VERSION, &gRenderAPI, &clgame.drawFuncs ))
|
||||
{
|
||||
MsgDev( D_REPORT, "CL_LoadProgs: ^2initailized extended RenderAPI ^7ver. %i\n", CL_RENDER_INTERFACE_VERSION );
|
||||
Con_Reportf( "CL_LoadProgs: ^2initailized extended RenderAPI ^7ver. %i\n", CL_RENDER_INTERFACE_VERSION );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,12 +27,8 @@ float V_CalcFov( float *fov_x, float width, float height )
|
|||
{
|
||||
float x, half_fov_y;
|
||||
|
||||
if( *fov_x < 1.0f || *fov_x > 170.0f )
|
||||
{
|
||||
if( !cls.demoplayback )
|
||||
MsgDev( D_ERROR, "V_CalcFov: bad fov %g!\n", *fov_x );
|
||||
*fov_x = 90.0f;
|
||||
}
|
||||
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 );
|
||||
|
|
|
@ -19,207 +19,7 @@ GNU General Public License for more details.
|
|||
#include "mod_local.h"
|
||||
#include "shake.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *texname;
|
||||
const char *detail;
|
||||
const char material;
|
||||
int lMin;
|
||||
int lMax;
|
||||
} dmaterial_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char texname[64]; // shortname
|
||||
imgfilter_t filter;
|
||||
} dfilter_t;
|
||||
|
||||
dfilter_t *tex_filters[MAX_TEXTURES];
|
||||
int num_texfilters;
|
||||
|
||||
// default rules for apply detail textures.
|
||||
// maybe move this to external script?
|
||||
static const dmaterial_t detail_table[] =
|
||||
{
|
||||
{ "crt", "dt_conc", 'C', 0, 0 }, // concrete
|
||||
{ "rock", "dt_rock1", 'C', 0, 0 },
|
||||
{ "conc", "dt_conc", 'C', 0, 0 },
|
||||
{ "brick", "dt_brick", 'C', 0, 0 },
|
||||
{ "wall", "dt_brick", 'C', 0, 0 },
|
||||
{ "city", "dt_conc", 'C', 0, 0 },
|
||||
{ "crete", "dt_conc", 'C', 0, 0 },
|
||||
{ "generic", "dt_brick", 'C', 0, 0 },
|
||||
{ "floor", "dt_conc", 'C', 0, 0 },
|
||||
{ "metal", "dt_metal%i", 'M', 1, 2 }, // metal
|
||||
{ "mtl", "dt_metal%i", 'M', 1, 2 },
|
||||
{ "pipe", "dt_metal%i", 'M', 1, 2 },
|
||||
{ "elev", "dt_metal%i", 'M', 1, 2 },
|
||||
{ "sign", "dt_metal%i", 'M', 1, 2 },
|
||||
{ "barrel", "dt_metal%i", 'M', 1, 2 },
|
||||
{ "bath", "dt_ssteel1", 'M', 1, 2 },
|
||||
{ "tech", "dt_ssteel1", 'M', 1, 2 },
|
||||
{ "refbridge", "dt_metal%i", 'M', 1, 2 },
|
||||
{ "panel", "dt_ssteel1", 'M', 0, 0 },
|
||||
{ "brass", "dt_ssteel1", 'M', 0, 0 },
|
||||
{ "rune", "dt_metal%i", 'M', 1, 2 },
|
||||
{ "car", "dt_metal%i", 'M', 1, 2 },
|
||||
{ "circuit", "dt_metal%i", 'M', 1, 2 },
|
||||
{ "steel", "dt_ssteel1", 'M', 0, 0 },
|
||||
{ "dirt", "dt_ground%i", 'D', 1, 5 }, // dirt
|
||||
{ "drt", "dt_ground%i", 'D', 1, 5 },
|
||||
{ "out", "dt_ground%i", 'D', 1, 5 },
|
||||
{ "grass", "dt_grass1", 'D', 0, 0 },
|
||||
{ "mud", "dt_carpet1", 'D', 0, 0 },
|
||||
{ "vent", "dt_ssteel1", 'V', 1, 4 }, // vent
|
||||
{ "duct", "dt_ssteel1", 'V', 1, 4 },
|
||||
{ "tile", "dt_smooth%i", 'T', 1, 2 },
|
||||
{ "labflr", "dt_smooth%i", 'T', 1, 2 },
|
||||
{ "bath", "dt_smooth%i", 'T', 1, 2 },
|
||||
{ "grate", "dt_stone%i", 'G', 1, 4 }, // vent
|
||||
{ "stone", "dt_stone%i", 'G', 1, 4 },
|
||||
{ "grt", "dt_stone%i", 'G', 1, 4 },
|
||||
{ "wiz", "dt_wood%i", 'W', 1, 3 },
|
||||
{ "wood", "dt_wood%i", 'W', 1, 3 },
|
||||
{ "wizwood", "dt_wood%i", 'W', 1, 3 },
|
||||
{ "wd", "dt_wood%i", 'W', 1, 3 },
|
||||
{ "table", "dt_wood%i", 'W', 1, 3 },
|
||||
{ "board", "dt_wood%i", 'W', 1, 3 },
|
||||
{ "chair", "dt_wood%i", 'W', 1, 3 },
|
||||
{ "brd", "dt_wood%i", 'W', 1, 3 },
|
||||
{ "carp", "dt_carpet1", 'W', 1, 3 },
|
||||
{ "book", "dt_wood%i", 'W', 1, 3 },
|
||||
{ "box", "dt_wood%i", 'W', 1, 3 },
|
||||
{ "cab", "dt_wood%i", 'W', 1, 3 },
|
||||
{ "couch", "dt_wood%i", 'W', 1, 3 },
|
||||
{ "crate", "dt_wood%i", 'W', 1, 3 },
|
||||
{ "poster", "dt_plaster%i", 'W', 1, 2 },
|
||||
{ "sheet", "dt_plaster%i", 'W', 1, 2 },
|
||||
{ "stucco", "dt_plaster%i", 'W', 1, 2 },
|
||||
{ "comp", "dt_smooth1", 'P', 0, 0 },
|
||||
{ "cmp", "dt_smooth1", 'P', 0, 0 },
|
||||
{ "elec", "dt_smooth1", 'P', 0, 0 },
|
||||
{ "vend", "dt_smooth1", 'P', 0, 0 },
|
||||
{ "monitor", "dt_smooth1", 'P', 0, 0 },
|
||||
{ "phone", "dt_smooth1", 'P', 0, 0 },
|
||||
{ "glass", "dt_ssteel1", 'Y', 0, 0 },
|
||||
{ "window", "dt_ssteel1", 'Y', 0, 0 },
|
||||
{ "flesh", "dt_rough1", 'F', 0, 0 },
|
||||
{ "meat", "dt_rough1", 'F', 0, 0 },
|
||||
{ "fls", "dt_rough1", 'F', 0, 0 },
|
||||
{ "ground", "dt_ground%i", 'D', 1, 5 },
|
||||
{ "gnd", "dt_ground%i", 'D', 1, 5 },
|
||||
{ "snow", "dt_snow%i", 'O', 1, 2 }, // snow
|
||||
{ "wswamp", "dt_smooth1", 'W', 0, 0 },
|
||||
{ NULL, NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static const char *R_DetailTextureForName( const char *name )
|
||||
{
|
||||
const dmaterial_t *table;
|
||||
|
||||
if( !name || !*name ) return NULL;
|
||||
if( !Q_strnicmp( name, "sky", 3 ))
|
||||
return NULL; // never details for sky
|
||||
|
||||
// never apply details for liquids
|
||||
if( !Q_strnicmp( name + 1, "!lava", 5 ))
|
||||
return NULL;
|
||||
if( !Q_strnicmp( name + 1, "!slime", 6 ))
|
||||
return NULL;
|
||||
if( !Q_strnicmp( name, "!cur_90", 7 ))
|
||||
return NULL;
|
||||
if( !Q_strnicmp( name, "!cur_0", 6 ))
|
||||
return NULL;
|
||||
if( !Q_strnicmp( name, "!cur_270", 8 ))
|
||||
return NULL;
|
||||
if( !Q_strnicmp( name, "!cur_180", 8 ))
|
||||
return NULL;
|
||||
if( !Q_strnicmp( name, "!cur_up", 7 ))
|
||||
return NULL;
|
||||
if( !Q_strnicmp( name, "!cur_dwn", 8 ))
|
||||
return NULL;
|
||||
if( name[0] == '!' )
|
||||
return NULL;
|
||||
|
||||
// never apply details to the special textures
|
||||
if( !Q_strnicmp( name, "origin", 6 ))
|
||||
return NULL;
|
||||
if( !Q_strnicmp( name, "clip", 4 ))
|
||||
return NULL;
|
||||
if( !Q_strnicmp( name, "hint", 4 ))
|
||||
return NULL;
|
||||
if( !Q_strnicmp( name, "skip", 4 ))
|
||||
return NULL;
|
||||
if( !Q_strnicmp( name, "translucent", 11 ))
|
||||
return NULL;
|
||||
if( !Q_strnicmp( name, "3dsky", 5 )) // xash-mod support :-)
|
||||
return NULL;
|
||||
if( !Q_strnicmp( name, "scroll", 6 ))
|
||||
return NULL;
|
||||
if( name[0] == '@' )
|
||||
return NULL;
|
||||
|
||||
// last check ...
|
||||
if( !Q_strnicmp( name, "null", 4 ))
|
||||
return NULL;
|
||||
|
||||
for( table = detail_table; table && table->texname; table++ )
|
||||
{
|
||||
if( Q_stristr( name, table->texname ))
|
||||
{
|
||||
if(( table->lMin + table->lMax ) > 0 )
|
||||
return va( table->detail, COM_RandomLong( table->lMin, table->lMax ));
|
||||
return table->detail;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void R_CreateDetailTexturesList( const char *filename )
|
||||
{
|
||||
file_t *detail_txt = NULL;
|
||||
float xScale, yScale;
|
||||
const char *detail_name;
|
||||
texture_t *tex;
|
||||
rgbdata_t *pic;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < cl.worldmodel->numtextures; i++ )
|
||||
{
|
||||
tex = cl.worldmodel->textures[i];
|
||||
detail_name = R_DetailTextureForName( tex->name );
|
||||
if( !detail_name ) continue;
|
||||
|
||||
// detailtexture detected
|
||||
if( detail_name )
|
||||
{
|
||||
if( !detail_txt ) detail_txt = FS_Open( filename, "w", false );
|
||||
if( !detail_txt )
|
||||
{
|
||||
MsgDev( D_ERROR, "Can't write %s\n", filename );
|
||||
break;
|
||||
}
|
||||
|
||||
pic = FS_LoadImage( va( "gfx/detail/%s", detail_name ), NULL, 0 );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
xScale = (pic->width / (float)tex->width) * gl_detailscale->value;
|
||||
yScale = (pic->height / (float)tex->height) * gl_detailscale->value;
|
||||
FS_FreeImage( pic );
|
||||
}
|
||||
else xScale = yScale = 10.0f;
|
||||
|
||||
// store detailtexture description
|
||||
FS_Printf( detail_txt, "%s detail/%s %.2f %.2f\n", tex->name, detail_name, xScale, yScale );
|
||||
}
|
||||
}
|
||||
|
||||
if( detail_txt ) FS_Close( detail_txt );
|
||||
}
|
||||
|
||||
void R_ParseDetailTextures( const char *filename )
|
||||
static void R_ParseDetailTextures( const char *filename )
|
||||
{
|
||||
char *afile, *pfile;
|
||||
string token, texname;
|
||||
|
@ -229,12 +29,6 @@ void R_ParseDetailTextures( const char *filename )
|
|||
texture_t *tex;
|
||||
int i;
|
||||
|
||||
if( r_detailtextures->value >= 2 && !FS_FileExists( filename, false ))
|
||||
{
|
||||
// use built-in generator for detail textures
|
||||
R_CreateDetailTexturesList( filename );
|
||||
}
|
||||
|
||||
afile = FS_LoadFile( filename, NULL, false );
|
||||
if( !afile ) return;
|
||||
|
||||
|
@ -292,12 +86,12 @@ void R_ParseDetailTextures( const char *filename )
|
|||
if( Q_stricmp( tex->name, texname ))
|
||||
continue;
|
||||
|
||||
tex->dt_texturenum = GL_LoadTexture( detail_path, NULL, 0, TF_FORCE_COLOR, NULL );
|
||||
tex->dt_texturenum = GL_LoadTexture( detail_path, NULL, 0, TF_FORCE_COLOR );
|
||||
|
||||
// texture is loaded
|
||||
if( tex->dt_texturenum )
|
||||
{
|
||||
gltexture_t *glt;
|
||||
gl_texture_t *glt;
|
||||
|
||||
glt = R_GetTexture( tex->gl_texturenum );
|
||||
glt->xscale = xScale;
|
||||
|
@ -310,116 +104,6 @@ void R_ParseDetailTextures( const char *filename )
|
|||
Mem_Free( afile );
|
||||
}
|
||||
|
||||
void R_ParseTexFilters( const char *filename )
|
||||
{
|
||||
char *afile, *pfile;
|
||||
string token, texname;
|
||||
dfilter_t *tf;
|
||||
int i;
|
||||
|
||||
afile = FS_LoadFile( filename, NULL, false );
|
||||
if( !afile ) return;
|
||||
|
||||
pfile = afile;
|
||||
|
||||
// format: 'texturename' 'filtername' 'factor' 'bias' 'blendmode' 'grayscale'
|
||||
while(( pfile = COM_ParseFile( pfile, token )) != NULL )
|
||||
{
|
||||
imgfilter_t filter;
|
||||
|
||||
memset( &filter, 0, sizeof( filter ));
|
||||
Q_strncpy( texname, token, sizeof( texname ));
|
||||
|
||||
// parse filter
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
if( !Q_stricmp( token, "blur" ))
|
||||
filter.filter = BLUR_FILTER;
|
||||
else if( !Q_stricmp( token, "blur2" ))
|
||||
filter.filter = BLUR_FILTER2;
|
||||
else if( !Q_stricmp( token, "edge" ))
|
||||
filter.filter = EDGE_FILTER;
|
||||
else if( !Q_stricmp( token, "emboss" ))
|
||||
filter.filter = EMBOSS_FILTER;
|
||||
|
||||
// reading factor
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
filter.factor = Q_atof( token );
|
||||
|
||||
// reading bias
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
filter.bias = Q_atof( token );
|
||||
|
||||
// reading blendFunc
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
if( !Q_stricmp( token, "modulate" ) || !Q_stricmp( token, "GL_MODULATE" ))
|
||||
filter.blendFunc = GL_MODULATE;
|
||||
else if( !Q_stricmp( token, "replace" ) || !Q_stricmp( token, "GL_REPLACE" ))
|
||||
filter.blendFunc = GL_REPLACE;
|
||||
else if( !Q_stricmp( token, "add" ) || !Q_stricmp( token, "GL_ADD" ))
|
||||
filter.blendFunc = GL_ADD;
|
||||
else if( !Q_stricmp( token, "decal" ) || !Q_stricmp( token, "GL_DECAL" ))
|
||||
filter.blendFunc = GL_DECAL;
|
||||
else if( !Q_stricmp( token, "blend" ) || !Q_stricmp( token, "GL_BLEND" ))
|
||||
filter.blendFunc = GL_BLEND;
|
||||
else if( !Q_stricmp( token, "add_signed" ) || !Q_stricmp( token, "GL_ADD_SIGNED" ))
|
||||
filter.blendFunc = GL_ADD_SIGNED;
|
||||
else MsgDev( D_WARN, "unknown blendFunc '%s' specified for texture '%s'\n", texname, token );
|
||||
|
||||
// reading flags
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
filter.flags = Q_atoi( token );
|
||||
|
||||
// make sure what factor is not zeroed
|
||||
if( filter.factor == 0.0f )
|
||||
{
|
||||
MsgDev( D_WARN, "texfilter for texture %s has factor 0! Ignored\n", texname );
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if already existed
|
||||
for( i = 0; i < num_texfilters; i++ )
|
||||
{
|
||||
tf = tex_filters[i];
|
||||
|
||||
if( !Q_stricmp( tf->texname, texname ))
|
||||
{
|
||||
MsgDev( D_WARN, "texture %s has specified multiple filters! Ignored\n", texname );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( i != num_texfilters )
|
||||
continue; // already specified
|
||||
|
||||
// allocate new texfilter
|
||||
tf = Z_Malloc( sizeof( dfilter_t ));
|
||||
tex_filters[num_texfilters++] = tf;
|
||||
|
||||
Q_strncpy( tf->texname, texname, sizeof( tf->texname ));
|
||||
tf->filter = filter;
|
||||
}
|
||||
|
||||
MsgDev( D_INFO, "%i texture filters parsed\n", num_texfilters );
|
||||
|
||||
Mem_Free( afile );
|
||||
}
|
||||
|
||||
imgfilter_t *R_FindTexFilter( const char *texname )
|
||||
{
|
||||
dfilter_t *tf;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < num_texfilters; i++ )
|
||||
{
|
||||
tf = tex_filters[i];
|
||||
|
||||
if( !Q_stricmp( tf->texname, texname ))
|
||||
return &tf->filter;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
R_ClearStaticEntities
|
||||
|
@ -451,7 +135,7 @@ void R_NewMap( void )
|
|||
R_ClearDecals(); // clear all level decals
|
||||
|
||||
// upload detailtextures
|
||||
if( r_detailtextures->value )
|
||||
if( CVAR_TO_BOOL( r_detailtextures ))
|
||||
{
|
||||
string mapname, filepath;
|
||||
|
||||
|
@ -462,12 +146,15 @@ void R_NewMap( void )
|
|||
R_ParseDetailTextures( filepath );
|
||||
}
|
||||
|
||||
if( v_dark->value )
|
||||
if( CVAR_TO_BOOL( v_dark ))
|
||||
{
|
||||
screenfade_t *sf = &clgame.fade;
|
||||
float fadetime = 5.0f;
|
||||
client_textmessage_t *title;
|
||||
|
||||
title = CL_TextMessageGet( "GAMETITLE" );
|
||||
if( Host_IsQuakeCompatible( ))
|
||||
fadetime = 1.0f;
|
||||
|
||||
if( title )
|
||||
{
|
||||
|
@ -475,7 +162,7 @@ void R_NewMap( void )
|
|||
sf->fadeEnd = title->holdtime + title->fadeout;
|
||||
sf->fadeReset = title->fadeout;
|
||||
}
|
||||
else sf->fadeEnd = sf->fadeReset = 5.0f;
|
||||
else sf->fadeEnd = sf->fadeReset = fadetime;
|
||||
|
||||
sf->fadeFlags = FFADE_IN;
|
||||
sf->fader = sf->fadeg = sf->fadeb = 0;
|
||||
|
@ -492,6 +179,7 @@ void R_NewMap( void )
|
|||
cl.worldmodel->leafs[i+1].efrags = NULL;
|
||||
|
||||
tr.skytexturenum = -1;
|
||||
tr.max_recursion = 0;
|
||||
pglDisable( GL_FOG );
|
||||
|
||||
// clearing texture chains
|
||||
|
@ -502,7 +190,7 @@ void R_NewMap( void )
|
|||
|
||||
tx = cl.worldmodel->textures[i];
|
||||
|
||||
if( !Q_strncmp( tx->name, "sky", 3 ) && tx->width == 256 && tx->height == 128 )
|
||||
if( !Q_strncmp( tx->name, "sky", 3 ) && tx->width == ( tx->height * 2 ))
|
||||
tr.skytexturenum = i;
|
||||
|
||||
tx->texturechain = NULL;
|
||||
|
|
|
@ -128,7 +128,7 @@ void CL_InitParticles( void )
|
|||
{
|
||||
int i;
|
||||
|
||||
cl_particles = Mem_Alloc( cls.mempool, sizeof( particle_t ) * GI->max_particles );
|
||||
cl_particles = Mem_Calloc( cls.mempool, sizeof( particle_t ) * GI->max_particles );
|
||||
CL_ClearParticles ();
|
||||
|
||||
// this is used for EF_BRIGHTFIELD
|
||||
|
@ -225,7 +225,7 @@ particle_t *R_AllocParticle( void (*callback)( particle_t*, float ))
|
|||
if( cl_lasttimewarn < host.realtime )
|
||||
{
|
||||
// don't spam about overflow
|
||||
MsgDev( D_ERROR, "Overflow %d particles\n", GI->max_particles );
|
||||
Con_DPrintf( S_ERROR "Overflow %d particles\n", GI->max_particles );
|
||||
cl_lasttimewarn = host.realtime + 1.0f;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -276,7 +276,7 @@ particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life )
|
|||
if( cl_lasttimewarn < host.realtime )
|
||||
{
|
||||
// don't spam about overflow
|
||||
MsgDev( D_ERROR, "Overflow %d tracers\n", GI->max_particles );
|
||||
Con_DPrintf( S_ERROR "Overflow %d tracers\n", GI->max_particles );
|
||||
cl_lasttimewarn = host.realtime + 1.0f;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -1501,14 +1501,11 @@ void R_UserTracerParticle( float *org, float *vel, float life, int colorIndex, f
|
|||
particle_t *p;
|
||||
|
||||
if( colorIndex < 0 )
|
||||
{
|
||||
MsgDev( D_ERROR, "UserTracer with color < 0\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( colorIndex > ARRAYSIZE( gTracerColors ))
|
||||
{
|
||||
MsgDev( D_ERROR, "UserTracer with color > %d\n", ARRAYSIZE( gTracerColors ));
|
||||
Con_Printf( S_ERROR "UserTracer with color > %d\n", ARRAYSIZE( gTracerColors ));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ static void SubdividePolygon_r( msurface_t *warpface, int numverts, float *verts
|
|||
ClearBits( warpface->flags, SURF_DRAWTURB_QUADS );
|
||||
|
||||
// add a point in the center to help keep warp valid
|
||||
poly = Mem_Alloc( loadmodel->mempool, sizeof( glpoly_t ) + (numverts - 4) * VERTEXSIZE * sizeof( float ));
|
||||
poly = Mem_Calloc( loadmodel->mempool, sizeof( glpoly_t ) + (numverts - 4) * VERTEXSIZE * sizeof( float ));
|
||||
poly->next = warpface->polys;
|
||||
poly->flags = warpface->flags;
|
||||
warpface->polys = poly;
|
||||
|
@ -273,20 +273,16 @@ void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa )
|
|||
medge_t *pedges, *r_pedge;
|
||||
mextrasurf_t *info = fa->info;
|
||||
float sample_size;
|
||||
int vertpage;
|
||||
texture_t *tex;
|
||||
gltexture_t *glt;
|
||||
gl_texture_t *glt;
|
||||
float *vec;
|
||||
float s, t;
|
||||
glpoly_t *poly;
|
||||
|
||||
// already created
|
||||
if( !mod || fa->polys ) return;
|
||||
|
||||
if( !fa->texinfo || !fa->texinfo->texture )
|
||||
if( !mod || !fa->texinfo || !fa->texinfo->texture )
|
||||
return; // bad polygon ?
|
||||
|
||||
if( fa->flags & SURF_CONVEYOR && fa->texinfo->texture->gl_texturenum != 0 )
|
||||
if( FBitSet( fa->flags, SURF_CONVEYOR ) && fa->texinfo->texture->gl_texturenum != 0 )
|
||||
{
|
||||
glt = R_GetTexture( fa->texinfo->texture->gl_texturenum );
|
||||
tex = fa->texinfo->texture;
|
||||
|
@ -302,10 +298,13 @@ void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa )
|
|||
// reconstruct the polygon
|
||||
pedges = mod->edges;
|
||||
lnumverts = fa->numedges;
|
||||
vertpage = 0;
|
||||
|
||||
// draw texture
|
||||
poly = Mem_Alloc( mod->mempool, sizeof( glpoly_t ) + ( lnumverts - 4 ) * VERTEXSIZE * sizeof( float ));
|
||||
// detach if already created, reconstruct again
|
||||
poly = fa->polys;
|
||||
fa->polys = NULL;
|
||||
|
||||
// quake simple models (healthkits etc) need to be reconstructed their polys because LM coords has changed after the map change
|
||||
poly = Mem_Realloc( mod->mempool, poly, sizeof( glpoly_t ) + ( lnumverts - 4 ) * VERTEXSIZE * sizeof( float ));
|
||||
poly->next = fa->polys;
|
||||
poly->flags = fa->flags;
|
||||
fa->polys = poly;
|
||||
|
@ -340,13 +339,13 @@ void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa )
|
|||
s = DotProduct( vec, info->lmvecs[0] ) + info->lmvecs[0][3];
|
||||
s -= info->lightmapmins[0];
|
||||
s += fa->light_s * sample_size;
|
||||
s += sample_size / 2.0;
|
||||
s += sample_size * 0.5f;
|
||||
s /= BLOCK_SIZE * sample_size; //fa->texinfo->texture->width;
|
||||
|
||||
t = DotProduct( vec, info->lmvecs[1] ) + info->lmvecs[1][3];
|
||||
t -= info->lightmapmins[1];
|
||||
t += fa->light_t * sample_size;
|
||||
t += sample_size / 2.0;
|
||||
t += sample_size * 0.5f;
|
||||
t /= BLOCK_SIZE * sample_size; //fa->texinfo->texture->height;
|
||||
|
||||
poly->verts[i][5] = s;
|
||||
|
@ -354,7 +353,7 @@ void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa )
|
|||
}
|
||||
|
||||
// remove co-linear points - Ed
|
||||
if( !gl_keeptjunctions->value && !( fa->flags & SURF_UNDERWATER ))
|
||||
if( !CVAR_TO_BOOL( gl_keeptjunctions ) && !FBitSet( fa->flags, SURF_UNDERWATER ))
|
||||
{
|
||||
for( i = 0; i < lnumverts; i++ )
|
||||
{
|
||||
|
@ -438,19 +437,10 @@ texture_t *R_TextureAnimation( msurface_t *s )
|
|||
{
|
||||
base = base->anim_next;
|
||||
|
||||
if( !base )
|
||||
{
|
||||
MsgDev( D_ERROR, "R_TextureAnimation: broken loop\n" );
|
||||
if( !base || ++count > MOD_FRAMES )
|
||||
return s->texinfo->texture;
|
||||
}
|
||||
|
||||
if( ++count > MOD_FRAMES )
|
||||
{
|
||||
MsgDev( D_ERROR, "R_TextureAnimation: infinite loop\n" );
|
||||
return s->texinfo->texture;
|
||||
}
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
|
@ -644,7 +634,7 @@ static void LM_UploadBlock( qboolean dynamic )
|
|||
r_lightmap.size = r_lightmap.width * r_lightmap.height * 4;
|
||||
r_lightmap.flags = IMAGE_HAS_COLOR;
|
||||
r_lightmap.buffer = gl_lms.lightmap_buffer;
|
||||
tr.lightmapTextures[i] = GL_LoadTextureInternal( lmName, &r_lightmap, TF_FONT|TF_ATLAS_PAGE, false );
|
||||
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" );
|
||||
|
@ -702,9 +692,9 @@ static void R_BuildLightMap( msurface_t *surf, byte *dest, int stride, qboolean
|
|||
{
|
||||
for( s = 0; s < smax; s++ )
|
||||
{
|
||||
dest[0] = min((bl[0] >> 7), 255 );
|
||||
dest[1] = min((bl[1] >> 7), 255 );
|
||||
dest[2] = min((bl[2] >> 7), 255 );
|
||||
dest[0] = Q_min((bl[0] >> 7), 255 );
|
||||
dest[1] = Q_min((bl[1] >> 7), 255 );
|
||||
dest[2] = Q_min((bl[2] >> 7), 255 );
|
||||
dest[3] = 255;
|
||||
|
||||
bl += 3;
|
||||
|
@ -733,12 +723,20 @@ void DrawGLPoly( glpoly_t *p, float xScale, float yScale )
|
|||
|
||||
if( p->flags & SURF_CONVEYOR )
|
||||
{
|
||||
gltexture_t *texture;
|
||||
float flConveyorSpeed;
|
||||
float flConveyorSpeed = 0.0f;
|
||||
float flRate, flAngle;
|
||||
gl_texture_t *texture;
|
||||
|
||||
if( Host_IsQuakeCompatible() && RI.currententity == clgame.entities )
|
||||
{
|
||||
// same as doom speed
|
||||
flConveyorSpeed = -35.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
flConveyorSpeed = (e->curstate.rendercolor.g<<8|e->curstate.rendercolor.b) / 16.0f;
|
||||
if( e->curstate.rendercolor.r ) flConveyorSpeed = -flConveyorSpeed;
|
||||
}
|
||||
texture = R_GetTexture( glState.currentTextures[glState.activeTMU] );
|
||||
|
||||
flRate = abs( flConveyorSpeed ) / (float)texture->srcWidth;
|
||||
|
@ -823,7 +821,7 @@ void R_BlendLightmaps( void )
|
|||
msurface_t *surf, *newsurf = NULL;
|
||||
int i;
|
||||
|
||||
if( r_fullbright->value || !cl.worldmodel->lightdata )
|
||||
if( CVAR_TO_BOOL( r_fullbright ) || !cl.worldmodel->lightdata )
|
||||
return;
|
||||
|
||||
if( RI.currententity )
|
||||
|
@ -844,7 +842,7 @@ void R_BlendLightmaps( void )
|
|||
|
||||
GL_SetupFogColorForSurfaces ();
|
||||
|
||||
if( !r_lightmap->value )
|
||||
if( !CVAR_TO_BOOL( r_lightmap ))
|
||||
pglEnable( GL_BLEND );
|
||||
else pglDisable( GL_BLEND );
|
||||
|
||||
|
@ -871,7 +869,7 @@ void R_BlendLightmaps( void )
|
|||
}
|
||||
|
||||
// render dynamic lightmaps
|
||||
if( r_dynamic->value )
|
||||
if( CVAR_TO_BOOL( r_dynamic ))
|
||||
{
|
||||
LM_InitBlock();
|
||||
|
||||
|
@ -1004,7 +1002,7 @@ R_RenderDetails
|
|||
*/
|
||||
void R_RenderDetails( void )
|
||||
{
|
||||
gltexture_t *glt;
|
||||
gl_texture_t *glt;
|
||||
mextrasurf_t *es, *p;
|
||||
msurface_t *fa;
|
||||
int i;
|
||||
|
@ -1081,7 +1079,7 @@ void R_RenderBrushPoly( msurface_t *fa, int cull_type )
|
|||
draw_fullbrights = true;
|
||||
}
|
||||
|
||||
if( r_detailtextures->value )
|
||||
if( CVAR_TO_BOOL( r_detailtextures ))
|
||||
{
|
||||
if( pglIsEnabled( GL_FOG ))
|
||||
{
|
||||
|
@ -1124,7 +1122,7 @@ void R_RenderBrushPoly( msurface_t *fa, int cull_type )
|
|||
DrawSurfaceDecals( fa, true, (cull_type == CULL_BACKSIDE));
|
||||
}
|
||||
|
||||
if( fa->flags & SURF_DRAWTILED )
|
||||
if( FBitSet( fa->flags, SURF_DRAWTILED ))
|
||||
return; // no lightmaps anyway
|
||||
|
||||
// check for lightmap modification
|
||||
|
@ -1231,7 +1229,7 @@ void R_DrawTextureChains( void )
|
|||
if(( s->flags & SURF_DRAWTURB ) && clgame.movevars.wateralpha < 1.0f )
|
||||
continue; // draw translucent water later
|
||||
|
||||
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ) && FBitSet( s->flags, SURF_TRANSPARENT ))
|
||||
if( Host_IsQuakeCompatible() && FBitSet( s->flags, SURF_TRANSPARENT ))
|
||||
{
|
||||
draw_alpha_surfaces = true;
|
||||
continue; // draw transparent surfaces later
|
||||
|
@ -1294,7 +1292,7 @@ void R_DrawAlphaTextureChains( void )
|
|||
GL_ResetFogColor();
|
||||
R_BlendLightmaps();
|
||||
RI.currententity->curstate.rendermode = kRenderNormal; // restore world rendermode
|
||||
pglAlphaFunc( GL_GREATER, 0.0f );
|
||||
pglAlphaFunc( GL_GREATER, DEFAULT_ALPHATEST );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1411,7 +1409,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( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
if( Host_IsQuakeCompatible( ))
|
||||
{
|
||||
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
pglColor4f( 1.0f, 1.0f, 1.0f, tr.blend );
|
||||
|
@ -1481,7 +1479,7 @@ void R_DrawBrushModel( cl_entity_t *e )
|
|||
if( rotated ) R_RotateForEntity( e );
|
||||
else R_TranslateForEntity( e );
|
||||
|
||||
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ) && FBitSet( clmodel->flags, MODEL_TRANSPARENT ))
|
||||
if( Host_IsQuakeCompatible() && FBitSet( clmodel->flags, MODEL_TRANSPARENT ))
|
||||
e->curstate.rendermode = kRenderTransAlpha;
|
||||
|
||||
e->visframe = tr.realframecount; // visible
|
||||
|
@ -1514,7 +1512,7 @@ void R_DrawBrushModel( cl_entity_t *e )
|
|||
|
||||
for( i = 0; i < clmodel->nummodelsurfaces; i++, psurf++ )
|
||||
{
|
||||
if( FBitSet( psurf->flags, SURF_DRAWTURB ) && !FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
if( FBitSet( psurf->flags, SURF_DRAWTURB ) && !Host_IsQuakeCompatible( ))
|
||||
{
|
||||
if( psurf->plane->type != PLANE_Z && !FBitSet( e->curstate.effects, EF_WATERSIDES ))
|
||||
continue;
|
||||
|
@ -1542,7 +1540,7 @@ void R_DrawBrushModel( cl_entity_t *e )
|
|||
}
|
||||
|
||||
// sort faces if needs
|
||||
if( !FBitSet( clmodel->flags, MODEL_LIQUID ) && e->curstate.rendermode == kRenderTransTexture && !gl_nosort->value )
|
||||
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 );
|
||||
|
||||
// draw sorted translucent surfaces
|
||||
|
@ -1564,9 +1562,10 @@ void R_DrawBrushModel( cl_entity_t *e )
|
|||
|
||||
e->curstate.rendermode = old_rendermode;
|
||||
pglDisable( GL_ALPHA_TEST );
|
||||
pglAlphaFunc( GL_GREATER, 0.0f );
|
||||
pglAlphaFunc( GL_GREATER, DEFAULT_ALPHATEST );
|
||||
pglDisable( GL_BLEND );
|
||||
pglDepthMask( GL_TRUE );
|
||||
R_DrawModelHull(); // draw before restore
|
||||
R_LoadIdentity(); // restore worldmatrix
|
||||
}
|
||||
|
||||
|
@ -1589,14 +1588,14 @@ void R_RecursiveWorldNode( mnode_t *node, uint clipflags )
|
|||
mleaf_t *pleaf;
|
||||
int c, side;
|
||||
float dot;
|
||||
|
||||
loc0:
|
||||
if( node->contents == CONTENTS_SOLID )
|
||||
return; // hit a solid leaf
|
||||
|
||||
if( node->visframe != tr.visframecount )
|
||||
return;
|
||||
|
||||
if( clipflags && !r_nocull->value )
|
||||
if( clipflags && !CVAR_TO_BOOL( r_nocull ))
|
||||
{
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
|
@ -1665,7 +1664,8 @@ void R_RecursiveWorldNode( mnode_t *node, uint clipflags )
|
|||
}
|
||||
|
||||
// recurse down the back side
|
||||
R_RecursiveWorldNode( node->children[!side], clipflags );
|
||||
node = node->children[!side];
|
||||
goto loc0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1862,6 +1862,8 @@ R_DrawWorld
|
|||
*/
|
||||
void R_DrawWorld( void )
|
||||
{
|
||||
double start, end;
|
||||
|
||||
// paranoia issues: when gl_renderer is "0" we need have something valid for currententity
|
||||
// to prevent crashing until HeadShield drawing.
|
||||
RI.currententity = clgame.entities;
|
||||
|
@ -1882,10 +1884,15 @@ void R_DrawWorld( void )
|
|||
|
||||
R_ClearSkyBox ();
|
||||
|
||||
start = Sys_DoubleTime();
|
||||
if( RI.drawOrtho )
|
||||
R_DrawWorldTopView( cl.worldmodel->nodes, RI.frustum.clipFlags );
|
||||
else R_RecursiveWorldNode( cl.worldmodel->nodes, RI.frustum.clipFlags );
|
||||
end = Sys_DoubleTime();
|
||||
|
||||
r_stats.t_world_node = end - start;
|
||||
|
||||
start = Sys_DoubleTime();
|
||||
R_DrawTextureChains();
|
||||
|
||||
if( !CL_IsDevOverviewMode( ))
|
||||
|
@ -1900,10 +1907,15 @@ void R_DrawWorld( void )
|
|||
R_DrawSkyBox();
|
||||
}
|
||||
|
||||
end = Sys_DoubleTime();
|
||||
|
||||
r_stats.t_world_draw = end - start;
|
||||
tr.num_draw_decals = 0;
|
||||
skychain = NULL;
|
||||
|
||||
R_DrawTriangleOutlines ();
|
||||
|
||||
R_DrawWorldHull();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1996,8 +2008,10 @@ void GL_CreateSurfaceLightmap( msurface_t *surf )
|
|||
mextrasurf_t *info = surf->info;
|
||||
byte *base;
|
||||
|
||||
if( !cl.worldmodel->lightdata ) return;
|
||||
if( surf->flags & SURF_DRAWTILED )
|
||||
if( !loadmodel->lightdata )
|
||||
return;
|
||||
|
||||
if( FBitSet( surf->flags, SURF_DRAWTILED ))
|
||||
return;
|
||||
|
||||
sample_size = Mod_SampleSizeForFace( surf );
|
||||
|
@ -2163,9 +2177,6 @@ void GL_BuildLightmaps( void )
|
|||
// now gamma and brightness are valid
|
||||
ClearBits( vid_brightness->flags, FCVAR_CHANGED );
|
||||
ClearBits( vid_gamma->flags, FCVAR_CHANGED );
|
||||
|
||||
if( !gl_keeptjunctions->value )
|
||||
MsgDev( D_INFO, "Eliminate %i vertexes\n", nColinElim );
|
||||
}
|
||||
|
||||
void GL_InitRandomTable( void )
|
||||
|
|
|
@ -69,16 +69,16 @@ static dframetype_t *R_SpriteLoadFrame( model_t *mod, void *pin, mspriteframe_t
|
|||
if( FBitSet( mod->flags, MODEL_CLIENT )) // it's a HUD sprite
|
||||
{
|
||||
Q_snprintf( texname, sizeof( texname ), "#HUD/%s(%s:%i%i).spr", sprite_name, group_suffix, num / 10, num % 10 );
|
||||
gl_texturenum = GL_LoadTexture( texname, pin, pinframe->width * pinframe->height * bytes, r_texFlags, NULL );
|
||||
gl_texturenum = GL_LoadTexture( texname, pin, pinframe->width * pinframe->height * bytes, r_texFlags );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( texname, sizeof( texname ), "#%s(%s:%i%i).spr", sprite_name, group_suffix, num / 10, num % 10 );
|
||||
gl_texturenum = GL_LoadTexture( texname, pin, pinframe->width * pinframe->height * bytes, r_texFlags, NULL );
|
||||
gl_texturenum = GL_LoadTexture( texname, pin, pinframe->width * pinframe->height * bytes, r_texFlags );
|
||||
}
|
||||
|
||||
// setup frame description
|
||||
pspriteframe = Mem_Alloc( mod->mempool, sizeof( mspriteframe_t ));
|
||||
pspriteframe = Mem_Malloc( mod->mempool, sizeof( mspriteframe_t ));
|
||||
pspriteframe->width = pinframe->width;
|
||||
pspriteframe->height = pinframe->height;
|
||||
pspriteframe->up = pinframe->origin[1];
|
||||
|
@ -111,12 +111,12 @@ static dframetype_t *R_SpriteLoadGroup( model_t *mod, void *pin, mspriteframe_t
|
|||
numframes = pingroup->numframes;
|
||||
|
||||
groupsize = sizeof( mspritegroup_t ) + (numframes - 1) * sizeof( pspritegroup->frames[0] );
|
||||
pspritegroup = Mem_Alloc( mod->mempool, groupsize );
|
||||
pspritegroup = Mem_Calloc( mod->mempool, groupsize );
|
||||
pspritegroup->numframes = numframes;
|
||||
|
||||
*ppframe = (mspriteframe_t *)pspritegroup;
|
||||
pin_intervals = (dspriteinterval_t *)(pingroup + 1);
|
||||
poutintervals = Mem_Alloc( mod->mempool, numframes * sizeof( float ));
|
||||
poutintervals = Mem_Calloc( mod->mempool, numframes * sizeof( float ));
|
||||
pspritegroup->intervals = poutintervals;
|
||||
|
||||
for( i = 0; i < numframes; i++ )
|
||||
|
@ -162,13 +162,13 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
|
|||
|
||||
if( pin->ident != IDSPRITEHEADER )
|
||||
{
|
||||
MsgDev( D_ERROR, "%s has wrong id (%x should be %x)\n", mod->name, 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 )
|
||||
{
|
||||
MsgDev( D_ERROR, "%s has wrong version number (%i should be %i or %i)\n", mod->name, i, SPRITE_VERSION_Q1, SPRITE_VERSION_HL );
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,7 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
|
|||
{
|
||||
pinq1 = (dsprite_q1_t *)buffer;
|
||||
size = sizeof( msprite_t ) + ( pinq1->numframes - 1 ) * sizeof( psprite->frames );
|
||||
psprite = Mem_Alloc( mod->mempool, size );
|
||||
psprite = Mem_Calloc( mod->mempool, size );
|
||||
mod->cache.data = psprite; // make link to extradata
|
||||
|
||||
psprite->type = pinq1->type;
|
||||
|
@ -189,6 +189,11 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
|
|||
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;
|
||||
|
@ -199,7 +204,7 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
|
|||
{
|
||||
pinhl = (dsprite_hl_t *)buffer;
|
||||
size = sizeof( msprite_t ) + ( pinhl->numframes - 1 ) * sizeof( psprite->frames );
|
||||
psprite = Mem_Alloc( mod->mempool, size );
|
||||
psprite = Mem_Calloc( mod->mempool, size );
|
||||
mod->cache.data = psprite; // make link to extradata
|
||||
|
||||
psprite->type = pinhl->type;
|
||||
|
@ -259,15 +264,12 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
|
|||
}
|
||||
else
|
||||
{
|
||||
MsgDev( D_ERROR, "%s has wrong number of palette colors %i (should be 256)\n", mod->name, *numi );
|
||||
Con_DPrintf( S_ERROR "%s has wrong number of palette colors %i (should be 256)\n", mod->name, *numi );
|
||||
return;
|
||||
}
|
||||
|
||||
if( mod->numframes < 1 )
|
||||
{
|
||||
MsgDev( D_ERROR, "%s has invalid # of frames: %d\n", mod->name, mod->numframes );
|
||||
return;
|
||||
}
|
||||
|
||||
for( i = 0; i < mod->numframes; i++ )
|
||||
{
|
||||
|
@ -336,7 +338,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, NULL );
|
||||
Image_Process( &pix, w, h, IMAGE_FORCE_RGBA|IMAGE_RESAMPLE, 0.0f );
|
||||
|
||||
w = h = MAPSPRITE_SIZE;
|
||||
|
||||
|
@ -347,7 +349,7 @@ void Mod_LoadMapSprite( model_t *mod, const void *buffer, size_t size, qboolean
|
|||
// determine how many frames we needs
|
||||
numframes = (pix->width * pix->height) / (w * h);
|
||||
mod->mempool = Mem_AllocPool( va( "^2%s^7", mod->name ));
|
||||
psprite = Mem_Alloc( mod->mempool, sizeof( msprite_t ) + ( numframes - 1 ) * sizeof( psprite->frames ));
|
||||
psprite = Mem_Calloc( mod->mempool, sizeof( msprite_t ) + ( numframes - 1 ) * sizeof( psprite->frames ));
|
||||
mod->cache.data = psprite; // make link to extradata
|
||||
|
||||
psprite->type = SPR_FWD_PARALLEL_ORIENTED;
|
||||
|
@ -367,7 +369,7 @@ void Mod_LoadMapSprite( model_t *mod, const void *buffer, size_t size, qboolean
|
|||
temp.type = pix->type;
|
||||
temp.flags = pix->flags;
|
||||
temp.size = w * h * PFDesc[temp.type].bpp;
|
||||
temp.buffer = Mem_Alloc( r_temppool, temp.size );
|
||||
temp.buffer = Mem_Malloc( r_temppool, temp.size );
|
||||
temp.palette = NULL;
|
||||
|
||||
// chop the image and upload into video memory
|
||||
|
@ -392,7 +394,7 @@ void Mod_LoadMapSprite( model_t *mod, const void *buffer, size_t size, qboolean
|
|||
// build uinque frame name
|
||||
Q_snprintf( texname, sizeof( texname ), "#MAP/%s_%i%i.spr", mod->name, i / 10, i % 10 );
|
||||
|
||||
psprite->frames[i].frameptr = Mem_Alloc( mod->mempool, sizeof( mspriteframe_t ));
|
||||
psprite->frames[i].frameptr = Mem_Calloc( mod->mempool, sizeof( mspriteframe_t ));
|
||||
pspriteframe = psprite->frames[i].frameptr;
|
||||
pspriteframe->width = w;
|
||||
pspriteframe->height = h;
|
||||
|
@ -400,7 +402,7 @@ void Mod_LoadMapSprite( model_t *mod, const void *buffer, size_t size, qboolean
|
|||
pspriteframe->left = -( w >> 1 );
|
||||
pspriteframe->down = ( h >> 1 ) - h;
|
||||
pspriteframe->right = w + -( w >> 1 );
|
||||
pspriteframe->gl_texturenum = GL_LoadTextureInternal( texname, &temp, TF_IMAGE, false );
|
||||
pspriteframe->gl_texturenum = GL_LoadTextureInternal( texname, &temp, TF_IMAGE );
|
||||
|
||||
xl += w;
|
||||
if( xl >= pix->width )
|
||||
|
@ -493,7 +495,7 @@ mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw )
|
|||
else if( frame >= psprite->numframes )
|
||||
{
|
||||
if( frame > psprite->numframes )
|
||||
MsgDev( D_WARN, "R_GetSpriteFrame: no such frame %d (%s)\n", frame, pModel->name );
|
||||
Con_Reportf( S_WARN "R_GetSpriteFrame: no such frame %d (%s)\n", frame, pModel->name );
|
||||
frame = psprite->numframes - 1;
|
||||
}
|
||||
|
||||
|
@ -561,7 +563,7 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe,
|
|||
}
|
||||
else if( frame >= psprite->numframes )
|
||||
{
|
||||
MsgDev( D_WARN, "R_GetSpriteFrameInterpolant: no such frame %d (%s)\n", frame, ent->model->name );
|
||||
Con_Reportf( S_WARN "R_GetSpriteFrameInterpolant: no such frame %d (%s)\n", frame, ent->model->name );
|
||||
frame = psprite->numframes - 1;
|
||||
}
|
||||
|
||||
|
@ -979,7 +981,7 @@ void R_DrawSpriteModel( cl_entity_t *e )
|
|||
color2[1] = (float)lightColor.g * ( 1.0f / 255.0f );
|
||||
color2[2] = (float)lightColor.b * ( 1.0f / 255.0f );
|
||||
// NOTE: sprites with 'lightmap' looks ugly when alpha func is GL_GREATER 0.0
|
||||
pglAlphaFunc( GL_GREATER, 0.25f );
|
||||
pglAlphaFunc( GL_GREATER, 0.5f );
|
||||
}
|
||||
|
||||
if( R_SpriteAllowLerping( e, psprite ))
|
||||
|
@ -1073,7 +1075,7 @@ void R_DrawSpriteModel( cl_entity_t *e )
|
|||
pglColor4f( color2[0], color2[1], color2[2], tr.blend );
|
||||
GL_Bind( XASH_TEXTURE0, tr.whiteTexture );
|
||||
R_DrawSpriteQuad( frame, origin, v_right, v_up, scale );
|
||||
pglAlphaFunc( GL_GREATER, 0.0f );
|
||||
pglAlphaFunc( GL_GREATER, DEFAULT_ALPHATEST );
|
||||
pglDepthFunc( GL_LEQUAL );
|
||||
}
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ void R_StudioInit( void )
|
|||
Matrix3x4_LoadIdentity( g_studio.rotationmatrix );
|
||||
Cvar_RegisterVariable( &r_glowshellfreq );
|
||||
|
||||
// g-cont. especially not registered
|
||||
// g-cont. cvar disabled by Valve
|
||||
// Cvar_RegisterVariable( &r_shadows );
|
||||
|
||||
g_studio.interpolate = true;
|
||||
|
@ -560,7 +560,7 @@ void R_StudioLerpMovement( cl_entity_t *e, double time, vec3_t origin, vec3_t an
|
|||
// Con_Printf( "%4.2f %.2f %.2f\n", f, e->curstate.animtime, g_studio.time );
|
||||
VectorLerp( e->latched.prevorigin, f, e->curstate.origin, origin );
|
||||
|
||||
if( !VectorCompare( e->curstate.angles, e->latched.prevangles ))
|
||||
if( !VectorCompareEpsilon( e->curstate.angles, e->latched.prevangles, ON_EPSILON ))
|
||||
{
|
||||
vec4_t q, q1, q2;
|
||||
|
||||
|
@ -718,6 +718,7 @@ float CL_GetSequenceDuration( cl_entity_t *ent, int sequence )
|
|||
return 0.1f;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
StudioFxTransform
|
||||
|
@ -794,8 +795,8 @@ void R_StudioCalcBoneAdj( float dadt, float *adj, const byte *pcontroller1, cons
|
|||
{
|
||||
if( abs( pcontroller1[i] - pcontroller2[i] ) > 128 )
|
||||
{
|
||||
int a = (pcontroller1[j] + 128) % 256;
|
||||
int b = (pcontroller2[j] + 128) % 256;
|
||||
int a = (pcontroller1[i] + 128) % 256;
|
||||
int b = (pcontroller2[i] + 128) % 256;
|
||||
value = (( a * dadt ) + ( b * ( 1.0f - dadt )) - 128) * (360.0f / 256.0f) + pbonecontroller[j].start;
|
||||
}
|
||||
else
|
||||
|
@ -1439,7 +1440,7 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight )
|
|||
}
|
||||
}
|
||||
|
||||
if(( light.r + light.g + light.b ) == 0 )
|
||||
if(( light.r + light.g + light.b ) < 16 ) // TESTTEST
|
||||
{
|
||||
colorVec gcolor;
|
||||
float grad[4];
|
||||
|
@ -1447,41 +1448,45 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight )
|
|||
VectorScale( lightDir, 2048.0f, vecEnd );
|
||||
VectorAdd( vecEnd, vecSrc, vecEnd );
|
||||
|
||||
light = R_LightVec( vecSrc, vecEnd, g_studio.lightspot );
|
||||
|
||||
VectorScale( lightDir, 2048.0f, vecEnd );
|
||||
VectorAdd( vecEnd, vecSrc, vecEnd );
|
||||
light = R_LightVec( vecSrc, vecEnd, g_studio.lightspot, g_studio.lightvec );
|
||||
|
||||
if( VectorIsNull( g_studio.lightvec ))
|
||||
{
|
||||
vecSrc[0] -= 16.0f;
|
||||
vecSrc[1] -= 16.0f;
|
||||
vecEnd[0] -= 16.0f;
|
||||
vecEnd[1] -= 16.0f;
|
||||
|
||||
gcolor = R_LightVec( vecSrc, vecEnd, NULL );
|
||||
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
|
||||
grad[0] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
|
||||
|
||||
vecSrc[0] += 32.0f;
|
||||
vecEnd[0] += 32.0f;
|
||||
|
||||
gcolor = R_LightVec( vecSrc, vecEnd, NULL );
|
||||
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
|
||||
grad[1] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
|
||||
|
||||
vecSrc[1] += 32.0f;
|
||||
vecEnd[1] += 32.0f;
|
||||
|
||||
gcolor = R_LightVec( vecSrc, vecEnd, NULL );
|
||||
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
|
||||
grad[2] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
|
||||
|
||||
vecSrc[0] -= 32.0f;
|
||||
vecEnd[0] -= 32.0f;
|
||||
|
||||
gcolor = R_LightVec( vecSrc, vecEnd, NULL );
|
||||
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
|
||||
grad[3] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
|
||||
|
||||
lightDir[0] = grad[0] - grad[1] - grad[2] + grad[3];
|
||||
lightDir[1] = grad[1] + grad[0] - grad[2] - grad[3];
|
||||
VectorNormalize( lightDir );
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy( g_studio.lightvec, lightDir );
|
||||
}
|
||||
}
|
||||
|
||||
VectorSet( finalLight, light.r, light.g, light.b );
|
||||
ent->cvFloorColor = light;
|
||||
|
@ -2172,6 +2177,7 @@ static void R_StudioDrawPoints( void )
|
|||
pglBlendFunc( GL_ONE, GL_ONE );
|
||||
pglDepthMask( GL_FALSE );
|
||||
pglEnable( GL_BLEND );
|
||||
R_AllowFog( false );
|
||||
}
|
||||
else pglBlendFunc( GL_SRC_ALPHA, GL_ONE );
|
||||
}
|
||||
|
@ -2186,13 +2192,14 @@ static void R_StudioDrawPoints( void )
|
|||
|
||||
if( FBitSet( g_nFaceFlags, STUDIO_NF_MASKED ))
|
||||
{
|
||||
pglAlphaFunc( GL_GREATER, 0.0f );
|
||||
pglAlphaFunc( GL_GREATER, DEFAULT_ALPHATEST );
|
||||
pglDisable( GL_ALPHA_TEST );
|
||||
}
|
||||
else if( FBitSet( g_nFaceFlags, STUDIO_NF_ADDITIVE ) && R_ModelOpaque( RI.currententity->curstate.rendermode ))
|
||||
{
|
||||
pglDepthMask( GL_TRUE );
|
||||
pglDisable( GL_BLEND );
|
||||
R_AllowFog( true );
|
||||
}
|
||||
|
||||
r_stats.c_studio_polys += pmesh->numtris;
|
||||
|
@ -2290,6 +2297,7 @@ static void R_StudioDrawAbsBBox( void )
|
|||
TriVertex3fv( p[boxpnt[i][3]] );
|
||||
}
|
||||
TriEnd();
|
||||
TriRenderMode( kRenderNormal );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2472,11 +2480,11 @@ check for texture flags
|
|||
*/
|
||||
int R_GetEntityRenderMode( cl_entity_t *ent )
|
||||
{
|
||||
studiohdr_t *phdr;
|
||||
int i, opaque, trans;
|
||||
mstudiotexture_t *ptexture;
|
||||
cl_entity_t *oldent;
|
||||
model_t *model;
|
||||
int i;
|
||||
studiohdr_t *phdr;
|
||||
|
||||
oldent = RI.currententity;
|
||||
RI.currententity = ent;
|
||||
|
@ -2488,22 +2496,28 @@ int R_GetEntityRenderMode( cl_entity_t *ent )
|
|||
RI.currententity = oldent;
|
||||
|
||||
if(( phdr = Mod_StudioExtradata( model )) == NULL )
|
||||
{
|
||||
if( R_ModelOpaque( ent->curstate.rendermode ))
|
||||
{
|
||||
// forcing to choose right sorting type
|
||||
if(( model && model->type == mod_brush ) && FBitSet( model->flags, MODEL_TRANSPARENT ))
|
||||
return kRenderTransAlpha;
|
||||
}
|
||||
return ent->curstate.rendermode;
|
||||
}
|
||||
ptexture = (mstudiotexture_t *)((byte *)phdr + phdr->textureindex);
|
||||
|
||||
for( i = 0; i < phdr->numtextures; i++, ptexture++ )
|
||||
for( opaque = trans = i = 0; i < phdr->numtextures; i++, ptexture++ )
|
||||
{
|
||||
// g-cont. this is not fully proper but better than was
|
||||
if( FBitSet( ptexture->flags, STUDIO_NF_ADDITIVE ))
|
||||
return kRenderTransAdd;
|
||||
// if( FBitSet( ptexture->flags, STUDIO_NF_MASKED ))
|
||||
// return kRenderTransAlpha;
|
||||
// ignore chrome & additive it's just a specular-like effect
|
||||
if( FBitSet( ptexture->flags, STUDIO_NF_ADDITIVE ) && !FBitSet( ptexture->flags, STUDIO_NF_CHROME ))
|
||||
trans++;
|
||||
else opaque++;
|
||||
}
|
||||
|
||||
// if model is more additive than opaque
|
||||
if( trans > opaque )
|
||||
return kRenderTransAdd;
|
||||
return ent->curstate.rendermode;
|
||||
}
|
||||
|
||||
|
@ -2885,6 +2899,13 @@ void R_StudioRenderFinal( void )
|
|||
pglVertex3fv( g_studio.lightspot );
|
||||
pglEnd();
|
||||
|
||||
pglBegin( GL_LINES );
|
||||
pglColor3f( 0, 0.5, 1 );
|
||||
VectorMA( g_studio.lightspot, -64.0f, g_studio.lightvec, origin );
|
||||
pglVertex3fv( g_studio.lightspot );
|
||||
pglVertex3fv( origin );
|
||||
pglEnd();
|
||||
|
||||
pglPointSize( 5.0f );
|
||||
pglColor3f( 1, 0, 0 );
|
||||
pglBegin( GL_POINTS );
|
||||
|
@ -3390,10 +3411,10 @@ void R_RunViewmodelEvents( void )
|
|||
|
||||
/*
|
||||
=================
|
||||
R_DrawViewModel
|
||||
R_GatherPlayerLight
|
||||
=================
|
||||
*/
|
||||
void R_DrawViewModel( void )
|
||||
void R_GatherPlayerLight( void )
|
||||
{
|
||||
cl_entity_t *view = &clgame.viewent;
|
||||
colorVec c;
|
||||
|
@ -3402,6 +3423,18 @@ void R_DrawViewModel( void )
|
|||
c = R_LightPoint( view->origin );
|
||||
tr.ignore_lightgamma = false;
|
||||
cl.local.light_level = (c.r + c.g + c.b) / 3;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_DrawViewModel
|
||||
=================
|
||||
*/
|
||||
void R_DrawViewModel( void )
|
||||
{
|
||||
cl_entity_t *view = &clgame.viewent;
|
||||
|
||||
R_GatherPlayerLight();
|
||||
|
||||
if( r_drawviewmodel->value == 0 )
|
||||
return;
|
||||
|
@ -3467,7 +3500,6 @@ static void R_StudioLoadTexture( model_t *mod, studiohdr_t *phdr, mstudiotexture
|
|||
size_t size;
|
||||
int flags = 0;
|
||||
char texname[128], name[128], mdlname[128];
|
||||
imgfilter_t *filter = NULL;
|
||||
texture_t *tx = NULL;
|
||||
|
||||
if( ptexture->flags & STUDIO_NF_NORMALMAP )
|
||||
|
@ -3483,7 +3515,7 @@ static void R_StudioLoadTexture( model_t *mod, studiohdr_t *phdr, mstudiotexture
|
|||
i = mod->numtextures;
|
||||
mod->textures = (texture_t **)Mem_Realloc( mod->mempool, mod->textures, ( i + 1 ) * sizeof( texture_t* ));
|
||||
size = ptexture->width * ptexture->height + 768;
|
||||
tx = Mem_Alloc( mod->mempool, sizeof( *tx ) + size );
|
||||
tx = Mem_Calloc( mod->mempool, sizeof( *tx ) + size );
|
||||
mod->textures[i] = tx;
|
||||
|
||||
// store ranges into anim_min, anim_max etc
|
||||
|
@ -3524,15 +3556,12 @@ static void R_StudioLoadTexture( model_t *mod, studiohdr_t *phdr, mstudiotexture
|
|||
COM_FileBase( ptexture->name, name );
|
||||
COM_StripExtension( mdlname );
|
||||
|
||||
// loading texture filter for studiomodel
|
||||
if( !FBitSet( ptexture->flags, STUDIO_NF_COLORMAP ))
|
||||
filter = R_FindTexFilter( va( "%s.mdl/%s", mdlname, name )); // grab texture filter
|
||||
|
||||
if( FBitSet( ptexture->flags, STUDIO_NF_NOMIPS ))
|
||||
SetBits( flags, TF_NOMIPMAP );
|
||||
|
||||
// NOTE: replace index with pointer to start of imagebuffer, ImageLib expected it
|
||||
ptexture->index = (int)((byte *)phdr) + ptexture->index;
|
||||
//ptexture->index = (int)((byte *)phdr) + ptexture->index;
|
||||
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 ))
|
||||
|
@ -3540,7 +3569,7 @@ static void R_StudioLoadTexture( model_t *mod, studiohdr_t *phdr, mstudiotexture
|
|||
|
||||
// build the texname
|
||||
Q_snprintf( texname, sizeof( texname ), "#%s/%s.mdl", mdlname, name );
|
||||
ptexture->index = GL_LoadTexture( texname, (byte *)ptexture, size, flags, filter );
|
||||
ptexture->index = GL_LoadTexture( texname, (byte *)ptexture, size, flags );
|
||||
|
||||
if( !ptexture->index )
|
||||
{
|
||||
|
|
|
@ -21,7 +21,7 @@ GNU General Public License for more details.
|
|||
#define SKYCLOUDS_QUALITY 12
|
||||
#define MAX_CLIP_VERTS 128 // skybox clip vertices
|
||||
#define TURBSCALE ( 256.0f / ( M_PI2 ))
|
||||
static const char* r_skyBoxSuffix[6] = { "rt", "bk", "lf", "ft", "up", "dn" };
|
||||
const char* r_skyBoxSuffix[6] = { "rt", "bk", "lf", "ft", "up", "dn" };
|
||||
static const int r_skyTexOrder[6] = { 0, 2, 1, 3, 4, 5 };
|
||||
|
||||
static const vec3_t skyclip[6] =
|
||||
|
@ -372,6 +372,9 @@ void R_DrawSkyBox( void )
|
|||
// don't fogging skybox (this fix old Half-Life bug)
|
||||
if( !RI.fogSkybox ) R_AllowFog( false );
|
||||
|
||||
if( RI.fogEnabled )
|
||||
pglFogf( GL_FOG_DENSITY, RI.fogDensity * 0.5f );
|
||||
|
||||
pglDisable( GL_BLEND );
|
||||
pglDisable( GL_ALPHA_TEST );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
|
||||
|
@ -395,6 +398,10 @@ void R_DrawSkyBox( void )
|
|||
|
||||
if( !RI.fogSkybox )
|
||||
R_AllowFog( true );
|
||||
|
||||
if( RI.fogEnabled )
|
||||
pglFogf( GL_FOG_DENSITY, RI.fogDensity );
|
||||
|
||||
R_LoadIdentity();
|
||||
}
|
||||
|
||||
|
@ -441,7 +448,7 @@ void R_SetupSky( const char *skyboxname )
|
|||
Q_snprintf( sidename, sizeof( sidename ), "%s%s", loadname, r_skyBoxSuffix[i] );
|
||||
else Q_snprintf( sidename, sizeof( sidename ), "%s_%s", loadname, r_skyBoxSuffix[i] );
|
||||
|
||||
tr.skyboxTextures[i] = GL_LoadTexture( sidename, NULL, 0, TF_CLAMP|TF_SKY, NULL );
|
||||
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 ? ", " : ". " );
|
||||
}
|
||||
|
@ -672,14 +679,14 @@ void R_InitSkyClouds( mip_t *mt, texture_t *tx, qboolean custom_palette )
|
|||
// make sure what sky image is valid
|
||||
if( !r_sky || !r_sky->palette || r_sky->type != PF_INDEXED_32 || r_sky->height == 0 )
|
||||
{
|
||||
MsgDev( D_ERROR, "R_InitSky: unable to load sky texture %s\n", tx->name );
|
||||
Con_Reportf( S_ERROR "R_InitSky: unable to load sky texture %s\n", tx->name );
|
||||
if( r_sky ) FS_FreeImage( r_sky );
|
||||
return;
|
||||
}
|
||||
|
||||
// make an average value for the back to avoid
|
||||
// a fringe on the top level
|
||||
trans = Mem_Alloc( r_temppool, r_sky->height * r_sky->height * sizeof( *trans ));
|
||||
trans = Mem_Malloc( r_temppool, r_sky->height * r_sky->height * sizeof( *trans ));
|
||||
r = g = b = 0;
|
||||
|
||||
for( i = 0; i < r_sky->width >> 1; i++ )
|
||||
|
@ -711,7 +718,7 @@ void R_InitSkyClouds( mip_t *mt, texture_t *tx, qboolean custom_palette )
|
|||
r_temp.palette = NULL;
|
||||
|
||||
// load it in
|
||||
tr.solidskyTexture = GL_LoadTextureInternal( "solid_sky", &r_temp, TF_NOMIPMAP, false );
|
||||
tr.solidskyTexture = GL_LoadTextureInternal( "solid_sky", &r_temp, TF_NOMIPMAP );
|
||||
|
||||
for( i = 0; i < r_sky->width >> 1; i++ )
|
||||
{
|
||||
|
@ -734,7 +741,7 @@ void R_InitSkyClouds( mip_t *mt, texture_t *tx, qboolean custom_palette )
|
|||
r_temp.flags = IMAGE_HAS_COLOR|IMAGE_HAS_ALPHA;
|
||||
|
||||
// load it in
|
||||
tr.alphaskyTexture = GL_LoadTextureInternal( "alpha_sky", &r_temp, TF_NOMIPMAP, false );
|
||||
tr.alphaskyTexture = GL_LoadTextureInternal( "alpha_sky", &r_temp, TF_NOMIPMAP );
|
||||
|
||||
// clean up
|
||||
FS_FreeImage( r_sky );
|
||||
|
|
|
@ -172,7 +172,7 @@ void Evdev_OpenDevice ( const char *path )
|
|||
ret = open( path, O_RDONLY | O_NONBLOCK );
|
||||
if( ret < 0 )
|
||||
{
|
||||
MsgDev( D_ERROR, "Could not open input device %s: %s\n", path, strerror( errno ) );
|
||||
Con_Reportf( S_ERROR "Could not open input device %s: %s\n", path, strerror( errno ) );
|
||||
return;
|
||||
}
|
||||
Msg( "Input device #%d: %s opened sucessfully\n", evdev.devices, path );
|
||||
|
@ -183,7 +183,7 @@ void Evdev_OpenDevice ( const char *path )
|
|||
void Evdev_OpenDevice_f( void )
|
||||
{
|
||||
if( Cmd_Argc() < 2 )
|
||||
Msg( "Usage: evdev_opendevice <path>\n" );
|
||||
Msg( S_USAGE "evdev_opendevice <path>\n" );
|
||||
|
||||
Evdev_OpenDevice( Cmd_Argv( 1 ) );
|
||||
}
|
||||
|
|
|
@ -21,10 +21,7 @@ GNU General Public License for more details.
|
|||
#include "keydefs.h"
|
||||
#include "client.h"
|
||||
#include "gl_local.h"
|
||||
|
||||
#if defined(XASH_SDL)
|
||||
#include "platform/sdl/events.h"
|
||||
#endif
|
||||
#include "platform/platform.h"
|
||||
|
||||
#ifndef SHRT_MAX
|
||||
#define SHRT_MAX 0x7FFF
|
||||
|
@ -62,28 +59,24 @@ static struct joy_axis_s
|
|||
short val;
|
||||
short prevval;
|
||||
} joyaxis[MAX_AXES] = { 0 };
|
||||
static qboolean initialized = false, forcedisable = false;
|
||||
static convar_t *joy_enable;
|
||||
static qboolean forcedisable = false;
|
||||
static byte currentbinding; // add posibility to remap keys, to place it in joykeys[]
|
||||
|
||||
float IN_TouchDrawText( float x1, float y1, float x2, float y2, const char *s, byte *color, float size );
|
||||
float IN_TouchDrawCharacter( float x, float y, int number, float size );
|
||||
|
||||
convar_t *joy_pitch;
|
||||
convar_t *joy_yaw;
|
||||
convar_t *joy_forward;
|
||||
convar_t *joy_side;
|
||||
convar_t *joy_found;
|
||||
convar_t *joy_index;
|
||||
convar_t *joy_lt_threshold;
|
||||
convar_t *joy_rt_threshold;
|
||||
convar_t *joy_side_deadzone;
|
||||
convar_t *joy_forward_deadzone;
|
||||
convar_t *joy_side_key_threshold;
|
||||
convar_t *joy_forward_key_threshold;
|
||||
convar_t *joy_pitch_deadzone;
|
||||
convar_t *joy_yaw_deadzone;
|
||||
convar_t *joy_axis_binding;
|
||||
static convar_t *joy_enable;
|
||||
static convar_t *joy_pitch;
|
||||
static convar_t *joy_yaw;
|
||||
static convar_t *joy_forward;
|
||||
static convar_t *joy_side;
|
||||
static convar_t *joy_found;
|
||||
static convar_t *joy_index;
|
||||
static convar_t *joy_lt_threshold;
|
||||
static convar_t *joy_rt_threshold;
|
||||
static convar_t *joy_side_deadzone;
|
||||
static convar_t *joy_forward_deadzone;
|
||||
static convar_t *joy_side_key_threshold;
|
||||
static convar_t *joy_forward_key_threshold;
|
||||
static convar_t *joy_pitch_deadzone;
|
||||
static convar_t *joy_yaw_deadzone;
|
||||
static convar_t *joy_axis_binding;
|
||||
|
||||
/*
|
||||
============
|
||||
|
@ -92,7 +85,7 @@ Joy_IsActive
|
|||
*/
|
||||
qboolean Joy_IsActive( void )
|
||||
{
|
||||
return !forcedisable && initialized;
|
||||
return !forcedisable && joy_found->value;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -117,7 +110,7 @@ void Joy_HatMotionEvent( int id, byte hat, byte value )
|
|||
};
|
||||
int i;
|
||||
|
||||
if( !initialized )
|
||||
if( !joy_found->value )
|
||||
return;
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( keys ); i++ )
|
||||
|
@ -155,7 +148,7 @@ void Joy_ProcessTrigger( const engineAxis_t engineAxis, short value )
|
|||
trigThreshold = joy_lt_threshold->value;
|
||||
break;
|
||||
default:
|
||||
MsgDev( D_ERROR, "Joy_ProcessTrigger: invalid axis = %i", engineAxis );
|
||||
Con_Reportf( S_ERROR "Joy_ProcessTrigger: invalid axis = %i", engineAxis );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -226,7 +219,7 @@ void Joy_ProcessStick( const engineAxis_t engineAxis, short value )
|
|||
case JOY_AXIS_PITCH: deadzone = joy_pitch_deadzone->value; break;
|
||||
case JOY_AXIS_YAW: deadzone = joy_yaw_deadzone->value; break;
|
||||
default:
|
||||
MsgDev( D_ERROR, "Joy_ProcessStick: invalid axis = %i", engineAxis );
|
||||
Con_Reportf( S_ERROR "Joy_ProcessStick: invalid axis = %i", engineAxis );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -261,12 +254,12 @@ void Joy_AxisMotionEvent( int id, byte axis, short value )
|
|||
{
|
||||
byte engineAxis;
|
||||
|
||||
if( !initialized )
|
||||
if( !joy_found->value )
|
||||
return;
|
||||
|
||||
if( axis >= MAX_AXES )
|
||||
{
|
||||
MsgDev( D_INFO, "Only 6 axes is supported\n" );
|
||||
Con_Reportf( "Only 6 axes is supported\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -293,7 +286,7 @@ Trackball events. UNDONE
|
|||
*/
|
||||
void Joy_BallMotionEvent( int id, byte ball, short xrel, short yrel )
|
||||
{
|
||||
//if( !initialized )
|
||||
//if( !joy_found->value )
|
||||
// return;
|
||||
}
|
||||
|
||||
|
@ -306,7 +299,7 @@ Button events
|
|||
*/
|
||||
void Joy_ButtonEvent( int id, byte button, byte down )
|
||||
{
|
||||
if( !initialized )
|
||||
if( !joy_found->value )
|
||||
return;
|
||||
|
||||
// generic game button code.
|
||||
|
@ -315,7 +308,7 @@ void Joy_ButtonEvent( int id, byte button, byte down )
|
|||
int origbutton = button;
|
||||
button = ( button & 31 ) + K_AUX1;
|
||||
|
||||
MsgDev( D_INFO, "Only 32 joybuttons is supported, converting %i button ID to %s\n", origbutton, Key_KeynumToString( button ) );
|
||||
Con_Reportf( "Only 32 joybuttons is supported, converting %i button ID to %s\n", origbutton, Key_KeynumToString( button ) );
|
||||
}
|
||||
else button += K_AUX1;
|
||||
|
||||
|
@ -331,7 +324,7 @@ Called when joystick is removed. For future expansion
|
|||
*/
|
||||
void Joy_RemoveEvent( int id )
|
||||
{
|
||||
if( !forcedisable && initialized && joy_found->value )
|
||||
if( !forcedisable && joy_found->value )
|
||||
Cvar_SetValue("joy_found", joy_found->value - 1.0f);
|
||||
}
|
||||
|
||||
|
@ -347,8 +340,6 @@ void Joy_AddEvent( int id )
|
|||
if( forcedisable )
|
||||
return;
|
||||
|
||||
initialized = true;
|
||||
|
||||
Cvar_SetValue("joy_found", joy_found->value + 1.0f);
|
||||
}
|
||||
|
||||
|
@ -361,7 +352,7 @@ Append movement from axis. Called everyframe
|
|||
*/
|
||||
void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw )
|
||||
{
|
||||
if( !initialized || !joy_enable->value )
|
||||
if( !joy_found->value || !joy_enable->value )
|
||||
return;
|
||||
|
||||
if( FBitSet( joy_axis_binding->flags, FCVAR_CHANGED ) )
|
||||
|
@ -440,19 +431,7 @@ void Joy_Init( void )
|
|||
return;
|
||||
}
|
||||
|
||||
#if defined(XASH_SDL)
|
||||
// SDL can tell us about connected joysticks
|
||||
Cvar_SetValue( "joy_found", SDLash_JoyInit( joy_index->value ) );
|
||||
#elif defined(ANDROID)
|
||||
// Initalized after first Joy_AddEvent
|
||||
#else
|
||||
#warning "Any platform must implement platform-dependent JoyInit, start event system. Otherwise no joystick support"
|
||||
#endif
|
||||
|
||||
if( joy_found->value > 0 )
|
||||
initialized = true;
|
||||
else
|
||||
initialized = false;
|
||||
Cvar_SetValue( "joy_found", Platform_JoyInit( joy_index->value ) );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -465,8 +444,6 @@ Shutdown joystick code
|
|||
void Joy_Shutdown( void )
|
||||
{
|
||||
Cvar_SetValue( "joy_found", 0 );
|
||||
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
#endif // XASH_DEDICATED
|
||||
|
|
|
@ -24,6 +24,7 @@ GNU General Public License for more details.
|
|||
#ifdef XASH_SDL
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
#include "platform/platform.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -173,7 +174,7 @@ void IN_TouchWriteConfig( void )
|
|||
if( Sys_CheckParm( "-nowriteconfig" ) || !touch.configchanged )
|
||||
return;
|
||||
|
||||
MsgDev( D_NOTE, "IN_TouchWriteConfig(): %s\n", touch_config_file->string );
|
||||
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 );
|
||||
|
@ -240,7 +241,7 @@ void IN_TouchWriteConfig( void )
|
|||
FS_Delete( touch_config_file->string );
|
||||
FS_Rename( newconfigfile, touch_config_file->string );
|
||||
}
|
||||
else MsgDev( D_ERROR, "Couldn't write %s.\n", touch_config_file->string );
|
||||
else Con_Reportf( S_ERROR "Couldn't write %s.\n", touch_config_file->string );
|
||||
}
|
||||
|
||||
void IN_TouchExportConfig_f( void )
|
||||
|
@ -250,7 +251,7 @@ void IN_TouchExportConfig_f( void )
|
|||
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
Msg( "Usage: touch_exportconfig <name>\n" );
|
||||
Msg( S_USAGE "touch_exportconfig <name>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -258,7 +259,7 @@ void IN_TouchExportConfig_f( void )
|
|||
|
||||
name = Cmd_Argv( 1 );
|
||||
|
||||
MsgDev( D_NOTE, "Exporting config to %s\n", name );
|
||||
Con_Reportf( "Exporting config to %s\n", name );
|
||||
f = FS_Open( name, "w", true );
|
||||
if( f )
|
||||
{
|
||||
|
@ -330,7 +331,7 @@ void IN_TouchExportConfig_f( void )
|
|||
FS_Printf( f, "touch_roundall\n" );
|
||||
FS_Close( f );
|
||||
}
|
||||
else MsgDev( D_ERROR, "Couldn't write %s.\n", name );
|
||||
else Con_Reportf( S_ERROR "Couldn't write %s.\n", name );
|
||||
}
|
||||
|
||||
void IN_TouchGenetateCode_f( void )
|
||||
|
@ -340,7 +341,7 @@ void IN_TouchGenetateCode_f( void )
|
|||
|
||||
if( Cmd_Argc() != 1 )
|
||||
{
|
||||
Msg( "Usage: touch_generate_code\n" );
|
||||
Msg( S_USAGE "touch_generate_code\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -584,7 +585,7 @@ void IN_TouchSetColor_f( void )
|
|||
IN_TouchSetColor( &touch.list_user, Cmd_Argv(1), color );
|
||||
return;
|
||||
}
|
||||
Msg( "Usage: touch_setcolor <pattern> <r> <g> <b> <a>\n" );
|
||||
Msg( S_USAGE "touch_setcolor <pattern> <r> <g> <b> <a>\n" );
|
||||
}
|
||||
|
||||
void IN_TouchSetTexture_f( void )
|
||||
|
@ -594,7 +595,7 @@ void IN_TouchSetTexture_f( void )
|
|||
IN_TouchSetTexture( &touch.list_user, Cmd_Argv( 1 ), Cmd_Argv( 2 ) );
|
||||
return;
|
||||
}
|
||||
Msg( "Usage: touch_settexture <name> <file>\n" );
|
||||
Msg( S_USAGE "touch_settexture <name> <file>\n" );
|
||||
}
|
||||
|
||||
void IN_TouchSetFlags_f( void )
|
||||
|
@ -606,7 +607,7 @@ void IN_TouchSetFlags_f( void )
|
|||
button->flags = Q_atoi( Cmd_Argv( 2 ) );
|
||||
return;
|
||||
}
|
||||
Msg( "Usage: touch_setflags <name> <file>\n" );
|
||||
Msg( S_USAGE "touch_setflags <name> <file>\n" );
|
||||
}
|
||||
|
||||
void IN_TouchSetCommand_f( void )
|
||||
|
@ -616,7 +617,7 @@ void IN_TouchSetCommand_f( void )
|
|||
IN_TouchSetCommand( &touch.list_user, Cmd_Argv( 1 ), Cmd_Argv( 2 ) );
|
||||
return;
|
||||
}
|
||||
Msg( "Usage: touch_command <name> <command>\n" );
|
||||
Msg( S_USAGE "touch_command <name> <command>\n" );
|
||||
}
|
||||
void IN_TouchReloadConfig_f( void )
|
||||
{
|
||||
|
@ -625,7 +626,7 @@ void IN_TouchReloadConfig_f( void )
|
|||
|
||||
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_Alloc( touch.mempool, sizeof( touchbutton2_t ) );
|
||||
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 );
|
||||
|
@ -779,7 +780,7 @@ void IN_TouchAddButton_f( void )
|
|||
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( "Usage: touch_addbutton <name> <texture> <command> [<x1> <y1> <x2> <y2> [ r g b a ] ]\n" );
|
||||
Msg( S_USAGE "touch_addbutton <name> <texture> <command> [<x1> <y1> <x2> <y2> [ r g b a ] ]\n" );
|
||||
}
|
||||
|
||||
void IN_TouchEnableEdit_f( void )
|
||||
|
@ -806,7 +807,7 @@ void IN_TouchDeleteProfile_f( void )
|
|||
{
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
Msg( "Usage: touch_deleteprofile <name>\n" );
|
||||
Msg( S_USAGE "touch_deleteprofile <name>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -822,7 +823,7 @@ void IN_TouchInit( void )
|
|||
return;
|
||||
touch.mempool = Mem_AllocPool( "Touch" );
|
||||
//touch.first = touch.last = NULL;
|
||||
MsgDev( D_NOTE, "IN_TouchInit()\n");
|
||||
Con_Reportf( "IN_TouchInit()\n");
|
||||
touch.move_finger = touch.resize_finger = touch.look_finger = -1;
|
||||
touch.state = state_none;
|
||||
touch.showbuttons = true;
|
||||
|
@ -907,9 +908,6 @@ void IN_TouchInit( void )
|
|||
|
||||
// input devices cvar
|
||||
touch_enable = Cvar_Get( "touch_enable", DEFAULT_TOUCH_ENABLE, FCVAR_ARCHIVE, "enable touch controls" );
|
||||
#if defined(XASH_SDL) && defined(__ANDROID__)
|
||||
SDL_SetHint( SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1" );
|
||||
#endif
|
||||
touch.initialized = true;
|
||||
}
|
||||
|
||||
|
@ -923,11 +921,11 @@ void IN_TouchInitConfig( void )
|
|||
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, NULL );
|
||||
touch.hidetexture = GL_LoadTexture( "touch_default/edit_hide.tga", NULL, 0, TF_NOMIPMAP, NULL );
|
||||
touch.showtexture = GL_LoadTexture( "touch_default/edit_show.tga", NULL, 0, TF_NOMIPMAP, NULL );
|
||||
touch.resettexture = GL_LoadTexture( "touch_default/edit_reset.tga", NULL, 0, TF_NOMIPMAP, NULL );
|
||||
touch.joytexture = GL_LoadTexture( touch_joy_texture->string, NULL, 0, TF_NOMIPMAP, NULL );
|
||||
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 )
|
||||
|
@ -1115,7 +1113,7 @@ void Touch_DrawButtons( touchbuttonlist_t *list )
|
|||
{
|
||||
if( button->texture == -1 )
|
||||
{
|
||||
button->texture = GL_LoadTexture( button->texturefile, NULL, 0, TF_NOMIPMAP, NULL );
|
||||
button->texture = GL_LoadTexture( button->texturefile, NULL, 0, TF_NOMIPMAP );
|
||||
}
|
||||
|
||||
if( B(flags) & TOUCH_FL_DRAW_ADDITIVE )
|
||||
|
@ -1260,7 +1258,7 @@ void IN_TouchDraw( void )
|
|||
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, NULL );
|
||||
touch.joytexture = GL_LoadTexture( touch_joy_texture->string, NULL, 0, TF_NOMIPMAP );
|
||||
}
|
||||
if( touch.move->type == touch_move )
|
||||
{
|
||||
|
@ -1451,7 +1449,7 @@ static qboolean Touch_ButtonPress( touchbuttonlist_t *list, touchEventType type,
|
|||
//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;
|
||||
MsgDev( D_NOTE, "Touch: touch_move on look finger %d!\n", fingerID );
|
||||
Con_Reportf( "Touch: touch_move on look finger %d!\n", fingerID );
|
||||
continue;
|
||||
}
|
||||
touch.move_finger = fingerID;
|
||||
|
@ -1490,7 +1488,7 @@ static qboolean Touch_ButtonPress( touchbuttonlist_t *list, touchEventType type,
|
|||
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;
|
||||
MsgDev( D_NOTE, "Touch: touch_look on move finger %d!\n", fingerID );
|
||||
Con_Reportf( "Touch: touch_look on move finger %d!\n", fingerID );
|
||||
continue;
|
||||
}
|
||||
touch.look_finger = fingerID;
|
||||
|
@ -1669,7 +1667,7 @@ int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx
|
|||
Cbuf_AddText( "escape\n" );
|
||||
}
|
||||
UI_MouseMove( TO_SCRN_X(x), TO_SCRN_Y(y) );
|
||||
//MsgDev( D_NOTE, "touch %d %d\n", 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 )
|
||||
|
@ -1728,7 +1726,7 @@ void IN_TouchKeyEvent( int key, int down )
|
|||
if( !touch.clientonly )
|
||||
return;
|
||||
|
||||
CL_GetMousePosition( &xi, &yi );
|
||||
Platform_GetMousePos( &xi, &yi );
|
||||
|
||||
x = xi/SCR_W;
|
||||
y = yi/SCR_H;
|
||||
|
|
|
@ -27,6 +27,8 @@ GNU General Public License for more details.
|
|||
#include "windows.h"
|
||||
#endif
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
void* in_mousecursor;
|
||||
qboolean in_mouseactive; // false when not focus app
|
||||
qboolean in_mouseinitialized;
|
||||
|
@ -101,10 +103,8 @@ void IN_MouseSavePos( void )
|
|||
if( !in_mouseactive )
|
||||
return;
|
||||
|
||||
#ifdef XASH_SDL
|
||||
SDL_GetMouseState( &in_lastvalidpos.x, &in_lastvalidpos.y );
|
||||
Platform_GetMousePos( &in_lastvalidpos.x, &in_lastvalidpos.y );
|
||||
in_mouse_savedpos = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -119,9 +119,7 @@ void IN_MouseRestorePos( void )
|
|||
if( !in_mouse_savedpos )
|
||||
return;
|
||||
|
||||
#ifdef XASH_SDL
|
||||
SDL_WarpMouseInWindow( host.hWnd, in_lastvalidpos.x, in_lastvalidpos.y );
|
||||
#endif
|
||||
Platform_SetMousePos( in_lastvalidpos.x, in_lastvalidpos.y );
|
||||
|
||||
in_mouse_savedpos = false;
|
||||
}
|
||||
|
@ -152,7 +150,7 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
|
|||
}
|
||||
else
|
||||
{
|
||||
SDL_WarpMouseInWindow( host.hWnd, host.window_center_x, host.window_center_y );
|
||||
Platform_SetMousePos( host.window_center_x, host.window_center_y );
|
||||
SDL_SetWindowGrab( host.hWnd, SDL_TRUE );
|
||||
if( clgame.dllFuncs.pfnLookEvent )
|
||||
SDL_SetRelativeMouseMode( SDL_TRUE );
|
||||
|
@ -282,9 +280,7 @@ void IN_MouseMove( void )
|
|||
return;
|
||||
|
||||
// find mouse movement
|
||||
#ifdef XASH_SDL
|
||||
SDL_GetMouseState( ¤t_pos.x, ¤t_pos.y );
|
||||
#endif
|
||||
Platform_GetMousePos( ¤t_pos.x, ¤t_pos.y );
|
||||
|
||||
VGui_MouseMove( current_pos.x, current_pos.y );
|
||||
|
||||
|
@ -321,7 +317,7 @@ void IN_MouseEvent( void )
|
|||
#if defined( XASH_SDL )
|
||||
static qboolean ignore; // igonre mouse warp event
|
||||
int x, y;
|
||||
SDL_GetMouseState(&x, &y);
|
||||
Platform_GetMousePos(&x, &y);
|
||||
if( host.mouse_visible )
|
||||
SDL_ShowCursor( SDL_TRUE );
|
||||
else
|
||||
|
@ -332,7 +328,7 @@ void IN_MouseEvent( void )
|
|||
x > host.window_center_x + host.window_center_x / 2 ||
|
||||
y > host.window_center_y + host.window_center_y / 2 )
|
||||
{
|
||||
SDL_WarpMouseInWindow(host.hWnd, host.window_center_x, host.window_center_y);
|
||||
Platform_SetMousePos( host.window_center_x, host.window_center_y );
|
||||
ignore = 1; // next mouse event will be mouse warp
|
||||
return;
|
||||
}
|
||||
|
@ -493,6 +489,47 @@ void IN_JoyAppendMove( usercmd_t *cmd, float forwardmove, float sidemove )
|
|||
}
|
||||
}
|
||||
|
||||
void IN_CollectInput( float *forward, float *side, float *pitch, float *yaw, qboolean includeMouse, qboolean includeSdlMouse )
|
||||
{
|
||||
if( !m_ignore->value || includeMouse )
|
||||
{
|
||||
#if XASH_INPUT == INPUT_SDL
|
||||
if( includeSdlMouse )
|
||||
{
|
||||
int x, y;
|
||||
SDL_GetRelativeMouseState( &x, &y );
|
||||
*pitch += y * m_pitch->value;
|
||||
*yaw -= x * m_yaw->value;
|
||||
}
|
||||
#endif // INPUT_SDL
|
||||
|
||||
#ifdef __ANDROID__
|
||||
{
|
||||
float x, y;
|
||||
Android_MouseMove( &x, &y );
|
||||
*pitch += y * m_pitch->value;
|
||||
*yaw -= x * m_yaw->value;
|
||||
}
|
||||
#endif // ANDROID
|
||||
|
||||
#ifdef USE_EVDEV
|
||||
IN_EvdevMove( yaw, pitch );
|
||||
#endif
|
||||
}
|
||||
|
||||
Joy_FinalizeMove( forward, side, yaw, pitch );
|
||||
IN_TouchMove( forward, side, yaw, pitch );
|
||||
|
||||
if( look_filter->value )
|
||||
{
|
||||
*pitch = ( inputstate.lastpitch + *pitch ) / 2;
|
||||
*yaw = ( inputstate.lastyaw + *yaw ) / 2;
|
||||
inputstate.lastpitch = *pitch;
|
||||
inputstate.lastyaw = *yaw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
IN_EngineAppendMove
|
||||
|
@ -502,7 +539,7 @@ Called from cl_main.c after generating command in client
|
|||
*/
|
||||
void IN_EngineAppendMove( float frametime, usercmd_t *cmd, qboolean active )
|
||||
{
|
||||
float forward, side, dpitch, dyaw;
|
||||
float forward, side, pitch, yaw;
|
||||
|
||||
if( clgame.dllFuncs.pfnLookEvent )
|
||||
return;
|
||||
|
@ -510,45 +547,18 @@ void IN_EngineAppendMove( float frametime, usercmd_t *cmd, qboolean active )
|
|||
if( cls.key_dest != key_game || cl.paused || cl.intermission )
|
||||
return;
|
||||
|
||||
forward = side = dpitch = dyaw = 0;
|
||||
forward = side = pitch = yaw = 0;
|
||||
|
||||
if(active)
|
||||
if( active )
|
||||
{
|
||||
float sensitivity = ( (float)RI.fov_x / (float)90.0f );
|
||||
#if XASH_INPUT == INPUT_SDL
|
||||
if( m_enginemouse->value && !m_ignore->value )
|
||||
{
|
||||
int mouse_x, mouse_y;
|
||||
SDL_GetRelativeMouseState( &mouse_x, &mouse_y );
|
||||
RI.viewangles[PITCH] += mouse_y * m_pitch->value * sensitivity;
|
||||
RI.viewangles[YAW] -= mouse_x * m_yaw->value * sensitivity;
|
||||
}
|
||||
#endif
|
||||
#ifdef __ANDROID__
|
||||
if( !m_ignore->value )
|
||||
{
|
||||
float mouse_x, mouse_y;
|
||||
Android_MouseMove( &mouse_x, &mouse_y );
|
||||
RI.viewangles[PITCH] += mouse_y * m_pitch->value * sensitivity;
|
||||
RI.viewangles[YAW] -= mouse_x * m_yaw->value * sensitivity;
|
||||
}
|
||||
#endif
|
||||
Joy_FinalizeMove( &forward, &side, &dyaw, &dpitch );
|
||||
IN_TouchMove( &forward, &side, &dyaw, &dpitch );
|
||||
IN_JoyAppendMove( cmd, forward, side );
|
||||
#ifdef USE_EVDEV
|
||||
IN_EvdevMove( &dyaw, &dpitch );
|
||||
#endif
|
||||
if( look_filter->value )
|
||||
{
|
||||
dpitch = ( inputstate.lastpitch + dpitch ) / 2;
|
||||
dyaw = ( inputstate.lastyaw + dyaw ) / 2;
|
||||
inputstate.lastpitch = dpitch;
|
||||
inputstate.lastyaw = dyaw;
|
||||
}
|
||||
|
||||
RI.viewangles[YAW] += dyaw * sensitivity;
|
||||
RI.viewangles[PITCH] += dpitch * sensitivity;
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
@ -573,37 +583,7 @@ void Host_InputFrame( void )
|
|||
|
||||
if( clgame.dllFuncs.pfnLookEvent )
|
||||
{
|
||||
int dx, dy;
|
||||
|
||||
#ifndef __ANDROID__
|
||||
if( in_mouseinitialized && !m_ignore->value )
|
||||
{
|
||||
SDL_GetRelativeMouseState( &dx, &dy );
|
||||
pitch += dy * m_pitch->value, yaw -= dx * m_yaw->value; //mouse speed
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __ANDROID__
|
||||
if( !m_ignore->value )
|
||||
{
|
||||
float mouse_x, mouse_y;
|
||||
Android_MouseMove( &mouse_x, &mouse_y );
|
||||
pitch += mouse_y * m_pitch->value, yaw -= mouse_x * m_yaw->value; //mouse speed
|
||||
}
|
||||
#endif
|
||||
|
||||
Joy_FinalizeMove( &forward, &side, &yaw, &pitch );
|
||||
IN_TouchMove( &forward, &side, &yaw, &pitch );
|
||||
#ifdef USE_EVDEV
|
||||
IN_EvdevMove( &yaw, &pitch );
|
||||
#endif
|
||||
if( look_filter->value )
|
||||
{
|
||||
pitch = ( inputstate.lastpitch + pitch ) / 2;
|
||||
yaw = ( inputstate.lastyaw + yaw ) / 2;
|
||||
inputstate.lastpitch = pitch;
|
||||
inputstate.lastyaw = yaw;
|
||||
}
|
||||
IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized, true );
|
||||
|
||||
if( cls.key_dest == key_game )
|
||||
{
|
||||
|
|
|
@ -87,7 +87,6 @@ enum
|
|||
JOY_HAT_LEFTUP = JOY_HAT_LEFT | JOY_HAT_UP,
|
||||
JOY_HAT_LEFTDOWN = JOY_HAT_LEFT | JOY_HAT_DOWN
|
||||
};
|
||||
extern convar_t *joy_found;
|
||||
|
||||
qboolean Joy_IsActive( void );
|
||||
void Joy_HatMotionEvent( int id, byte hat, byte value );
|
||||
|
|
|
@ -17,13 +17,12 @@ GNU General Public License for more details.
|
|||
#include "input.h"
|
||||
#include "client.h"
|
||||
#include "vgui_draw.h"
|
||||
#ifdef XASH_SDL
|
||||
#include "platform/sdl/events.h"
|
||||
#endif // XASH_SDL
|
||||
#include "platform/platform.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
qboolean down;
|
||||
qboolean gamedown;
|
||||
int repeats; // if > 1, it is autorepeating
|
||||
const char *binding;
|
||||
} enginekey_t;
|
||||
|
@ -52,6 +51,7 @@ keyname_t keynames[] =
|
|||
{"CTRL", K_CTRL, "+attack" },
|
||||
{"SHIFT", K_SHIFT, "+speed" },
|
||||
{"CAPSLOCK", K_CAPSLOCK, "" },
|
||||
{"SCROLLOCK", K_SCROLLOCK, "" },
|
||||
{"F1", K_F1, "cmd help" },
|
||||
{"F2", K_F2, "menu_savegame" },
|
||||
{"F3", K_F3, "menu_loadgame" },
|
||||
|
@ -205,7 +205,7 @@ const char *Key_KeynumToString( int keynum )
|
|||
if ( keynum < 0 || keynum > 255 ) return "<OUT OF RANGE>";
|
||||
|
||||
// check for printable ascii (don't use quote)
|
||||
if( keynum > 32 && keynum < 127 && keynum != '"' && keynum != ';' )
|
||||
if( keynum > 32 && keynum < 127 && keynum != '"' && keynum != ';' && keynum != K_SCROLLOCK )
|
||||
{
|
||||
tinystr[0] = keynum;
|
||||
tinystr[1] = 0;
|
||||
|
@ -269,17 +269,28 @@ const char *Key_GetBinding( int keynum )
|
|||
Key_GetKey
|
||||
===================
|
||||
*/
|
||||
int Key_GetKey( const char *binding )
|
||||
int Key_GetKey( const char *pBinding )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( !binding ) return -1;
|
||||
if( !pBinding ) return -1;
|
||||
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
if( keys[i].binding && !Q_stricmp( binding, keys[i].binding ))
|
||||
if( !keys[i].binding )
|
||||
continue;
|
||||
|
||||
if( *keys[i].binding == '+' )
|
||||
{
|
||||
if( !Q_strnicmp( keys[i].binding + 1, pBinding, Q_strlen( pBinding )))
|
||||
return i;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !Q_strnicmp( keys[i].binding, pBinding, Q_strlen( pBinding )))
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -411,7 +422,9 @@ void Key_WriteBindings( file_t *f )
|
|||
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
if( keys[i].binding && keys[i].binding[0] )
|
||||
if( !COM_CheckString( keys[i].binding ))
|
||||
continue;
|
||||
|
||||
FS_Printf( f, "bind %s \"%s\"\n", Key_KeynumToString( i ), keys[i].binding );
|
||||
}
|
||||
}
|
||||
|
@ -428,7 +441,9 @@ void Key_Bindlist_f( void )
|
|||
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
if( keys[i].binding && keys[i].binding[0] )
|
||||
if( !COM_CheckString( keys[i].binding ))
|
||||
continue;
|
||||
|
||||
Con_Printf( "%s \"%s\"\n", Key_KeynumToString( i ), keys[i].binding );
|
||||
}
|
||||
}
|
||||
|
@ -463,18 +478,17 @@ void Key_Init( void )
|
|||
|
||||
/*
|
||||
===================
|
||||
Key_AddKeyUpCommands
|
||||
Key_AddKeyCommands
|
||||
===================
|
||||
*/
|
||||
void Key_AddKeyUpCommands( int key, const char *kb )
|
||||
void Key_AddKeyCommands( int key, const char *kb, qboolean down )
|
||||
{
|
||||
int i;
|
||||
char button[1024], *buttonPtr;
|
||||
char button[1024];
|
||||
char *buttonPtr;
|
||||
char cmd[1024];
|
||||
qboolean keyevent;
|
||||
int i;
|
||||
|
||||
if( !kb ) return;
|
||||
keyevent = false;
|
||||
buttonPtr = button;
|
||||
|
||||
for( i = 0; ; i++ )
|
||||
|
@ -485,19 +499,16 @@ void Key_AddKeyUpCommands( int key, const char *kb )
|
|||
if( button[0] == '+' )
|
||||
{
|
||||
// button commands add keynum as a parm
|
||||
Q_sprintf( cmd, "-%s %i\n", button+1, key );
|
||||
if( down ) Q_sprintf( cmd, "%s %i\n", button, key );
|
||||
else Q_sprintf( cmd, "-%s %i\n", button + 1, key );
|
||||
Cbuf_AddText( cmd );
|
||||
keyevent = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( keyevent )
|
||||
else if( down )
|
||||
{
|
||||
// down-only command
|
||||
Cbuf_AddText( button );
|
||||
Cbuf_AddText( "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
buttonPtr = button;
|
||||
while(( kb[i] <= ' ' || kb[i] == ';' ) && kb[i] != 0 )
|
||||
|
@ -509,6 +520,29 @@ void Key_AddKeyUpCommands( int key, const char *kb )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
Key_IsAllowedAutoRepeat
|
||||
|
||||
List of keys that allows auto-repeat
|
||||
===================
|
||||
*/
|
||||
qboolean Key_IsAllowedAutoRepeat( int key )
|
||||
{
|
||||
switch( key )
|
||||
{
|
||||
case K_BACKSPACE:
|
||||
case K_PAUSE:
|
||||
case K_PGUP:
|
||||
case K_KP_PGUP:
|
||||
case K_PGDN:
|
||||
case K_KP_PGDN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
Key_Event
|
||||
|
@ -519,30 +553,58 @@ Called by the system for both key up and key down events
|
|||
void Key_Event( int key, int down )
|
||||
{
|
||||
const char *kb;
|
||||
char cmd[1024];
|
||||
|
||||
// key was pressed before engine was run
|
||||
if( !keys[key].down && !down )
|
||||
return;
|
||||
|
||||
// update auto-repeat status and BUTTON_ANY status
|
||||
kb = keys[key].binding;
|
||||
keys[key].down = down;
|
||||
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
if(( cls.key_dest == key_game ) && ( cls.state == ca_cinematic ) && ( key != K_ESCAPE || !down ))
|
||||
{
|
||||
// only escape passed when cinematic is playing
|
||||
// HLFX 0.6 bug: crash in vgui3.dll while press +attack during movie playback
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// distribute the key down event to the apropriate handler
|
||||
if( cls.key_dest == key_game && ( down || keys[key].gamedown ))
|
||||
{
|
||||
if( !clgame.dllFuncs.pfnKey_Event( down, key, keys[key].binding ))
|
||||
{
|
||||
if( keys[key].repeats == 0 && down )
|
||||
{
|
||||
keys[key].gamedown = true;
|
||||
}
|
||||
|
||||
if( !down )
|
||||
{
|
||||
keys[key].gamedown = false;
|
||||
keys[key].repeats = 0;
|
||||
}
|
||||
return; // handled in client.dll
|
||||
}
|
||||
}
|
||||
|
||||
// update auto-repeat status
|
||||
if( down )
|
||||
{
|
||||
keys[key].repeats++;
|
||||
|
||||
if( key != K_BACKSPACE && key != K_PAUSE && keys[key].repeats > 1 )
|
||||
{
|
||||
if( cls.key_dest == key_game )
|
||||
if( !Key_IsAllowedAutoRepeat( key ) && keys[key].repeats > 1 )
|
||||
{
|
||||
// ignore most autorepeats
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( key >= 200 && !kb )
|
||||
Con_Printf( "%s is unbound.\n", Key_KeynumToString( key ));
|
||||
}
|
||||
else
|
||||
{
|
||||
keys[key].gamedown = false;
|
||||
keys[key].repeats = 0;
|
||||
}
|
||||
|
||||
|
@ -565,13 +627,13 @@ void Key_Event( int key, int down )
|
|||
switch( cls.key_dest )
|
||||
{
|
||||
case key_game:
|
||||
if( gl_showtextures->value )
|
||||
if( CVAR_TO_BOOL( gl_showtextures ))
|
||||
{
|
||||
// close texture atlas
|
||||
Cvar_SetValue( "r_showtextures", 0.0f );
|
||||
return;
|
||||
}
|
||||
if( host.mouse_visible && cls.state != ca_cinematic )
|
||||
else if( host.mouse_visible && cls.state != ca_cinematic )
|
||||
{
|
||||
clgame.dllFuncs.pfnKey_Event( down, key, keys[key].binding );
|
||||
return; // handled in client.dll
|
||||
|
@ -588,9 +650,7 @@ void Key_Event( int key, int down )
|
|||
case key_menu:
|
||||
UI_KeyEvent( key, true );
|
||||
return;
|
||||
default:
|
||||
MsgDev( D_ERROR, "Key_Event: bad cls.key_dest\n" );
|
||||
return;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -618,72 +678,14 @@ void Key_Event( int key, int down )
|
|||
// an action started before a mode switch.
|
||||
if( !down )
|
||||
{
|
||||
kb = keys[key].binding;
|
||||
|
||||
if( cls.key_dest == key_game && ( key != K_ESCAPE ))
|
||||
clgame.dllFuncs.pfnKey_Event( down, key, kb );
|
||||
|
||||
Key_AddKeyUpCommands( key, kb );
|
||||
Key_AddKeyCommands( key, kb, down );
|
||||
return;
|
||||
}
|
||||
|
||||
// distribute the key down event to the apropriate handler
|
||||
if( cls.key_dest == key_game )
|
||||
{
|
||||
if( cls.state == ca_cinematic && ( key != K_ESCAPE || !down ))
|
||||
{
|
||||
// only escape passed when cinematic is playing
|
||||
// HLFX 0.6 bug: crash in vgui3.dll while press +attack during movie playback
|
||||
return;
|
||||
}
|
||||
|
||||
// send the bound action
|
||||
kb = keys[key].binding;
|
||||
|
||||
if( !clgame.dllFuncs.pfnKey_Event( down, key, keys[key].binding ))
|
||||
{
|
||||
// handled in client.dll
|
||||
}
|
||||
else if( kb != NULL )
|
||||
{
|
||||
if( kb[0] == '+' )
|
||||
{
|
||||
int i;
|
||||
char button[1024], *buttonPtr;
|
||||
|
||||
for( i = 0, buttonPtr = button; ; i++ )
|
||||
{
|
||||
if( kb[i] == ';' || !kb[i] )
|
||||
{
|
||||
*buttonPtr = '\0';
|
||||
if( button[0] == '+' )
|
||||
{
|
||||
Q_sprintf( cmd, "%s %i\n", button, key );
|
||||
Cbuf_AddText( cmd );
|
||||
}
|
||||
else
|
||||
{
|
||||
// down-only command
|
||||
Cbuf_AddText( button );
|
||||
Cbuf_AddText( "\n" );
|
||||
}
|
||||
|
||||
buttonPtr = button;
|
||||
while (( kb[i] <= ' ' || kb[i] == ';' ) && kb[i] != 0 )
|
||||
i++;
|
||||
}
|
||||
|
||||
*buttonPtr++ = kb[i];
|
||||
if( !kb[i] ) break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// down-only command
|
||||
Cbuf_AddText( kb );
|
||||
Cbuf_AddText( "\n" );
|
||||
}
|
||||
}
|
||||
Key_AddKeyCommands( key, kb, down );
|
||||
}
|
||||
else if( cls.key_dest == key_console )
|
||||
{
|
||||
|
@ -703,20 +705,10 @@ Key_EnableTextInput
|
|||
*/
|
||||
void Key_EnableTextInput( qboolean enable, qboolean force )
|
||||
{
|
||||
void (*pfnEnableTextInput)( qboolean enable );
|
||||
|
||||
#if XASH_INPUT == INPUT_SDL
|
||||
pfnEnableTextInput = SDLash_EnableTextInput;
|
||||
#elif XASH_INPUT == INPUT_ANDROID
|
||||
pfnEnableTextInput = Android_EnableTextInput;
|
||||
#else
|
||||
#error "Here must be a text input for your platform"
|
||||
return;
|
||||
#endif
|
||||
if( enable && ( !host.textmode || force ) )
|
||||
pfnEnableTextInput( true );
|
||||
Platform_EnableTextInput( true );
|
||||
else if( !enable )
|
||||
pfnEnableTextInput( false );
|
||||
Platform_EnableTextInput( false );
|
||||
|
||||
if( !force )
|
||||
host.textmode = enable;
|
||||
|
@ -774,6 +766,7 @@ void Key_ClearStates( void )
|
|||
|
||||
keys[i].down = 0;
|
||||
keys[i].repeats = 0;
|
||||
keys[i].gamedown = 0;
|
||||
}
|
||||
|
||||
if( clgame.hInstance )
|
||||
|
|
778
engine/client/mod_dbghulls.c
Normal file
778
engine/client/mod_dbghulls.c
Normal file
|
@ -0,0 +1,778 @@
|
|||
/*
|
||||
mod_bmodel.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 "mod_local.h"
|
||||
#include "mathlib.h"
|
||||
#include "world.h"
|
||||
#include "gl_local.h"
|
||||
#include "client.h"
|
||||
|
||||
#define MAX_CLIPNODE_DEPTH 256 // should never exceeds
|
||||
|
||||
#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 ))
|
||||
|
||||
// iterate over the list, safe for removal of entries
|
||||
#define list_for_each_entry_safe( pos, n, head, member ) \
|
||||
for( pos = list_entry( (head)->next, winding_t, member ), \
|
||||
n = list_entry( pos->member.next, winding_t, member ); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry( n->member.next, winding_t, member ))
|
||||
|
||||
#define LIST_HEAD_INIT( name ) { &(name), &(name) }
|
||||
|
||||
_inline void list_add__( hullnode_t *new, hullnode_t *prev, hullnode_t *next )
|
||||
{
|
||||
next->prev = new;
|
||||
new->next = next;
|
||||
new->prev = prev;
|
||||
prev->next = new;
|
||||
}
|
||||
|
||||
// add the new entry after the give list entry
|
||||
_inline void list_add( hullnode_t *newobj, hullnode_t *head )
|
||||
{
|
||||
list_add__( newobj, head, head->next );
|
||||
}
|
||||
|
||||
// add the new entry before the given list entry (list is circular)
|
||||
_inline void list_add_tail( hullnode_t *newobj, hullnode_t *head )
|
||||
{
|
||||
list_add__( newobj, head->prev, head );
|
||||
}
|
||||
|
||||
_inline void list_del( hullnode_t *entry )
|
||||
{
|
||||
entry->next->prev = entry->prev;
|
||||
entry->prev->next = entry->next;
|
||||
}
|
||||
|
||||
static winding_t * winding_alloc( uint numpoints )
|
||||
{
|
||||
return (winding_t *)malloc( (int)((winding_t *)0)->p[numpoints] );
|
||||
}
|
||||
|
||||
static void free_winding( winding_t *w )
|
||||
{
|
||||
// simple sentinel by Carmack
|
||||
if( *(unsigned *)w == 0xDEADC0DE )
|
||||
Host_Error( "free_winding: freed a freed winding\n" );
|
||||
*(unsigned *)w = 0xDEADC0DE;
|
||||
free( w );
|
||||
}
|
||||
|
||||
static winding_t *winding_copy( winding_t *w )
|
||||
{
|
||||
winding_t *neww;
|
||||
|
||||
neww = winding_alloc( w->numpoints );
|
||||
memcpy( neww, w, (int)((winding_t *)0)->p[w->numpoints] );
|
||||
|
||||
return neww;
|
||||
}
|
||||
|
||||
static void winding_reverse( winding_t *w )
|
||||
{
|
||||
vec3_t point;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < w->numpoints / 2; i++ )
|
||||
{
|
||||
VectorCopy( w->p[i], point );
|
||||
VectorCopy( w->p[w->numpoints - i - 1], w->p[i] );
|
||||
VectorCopy( point, w->p[w->numpoints - i - 1] );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* winding_shrink
|
||||
*
|
||||
* Takes an over-allocated winding and allocates a new winding with just the
|
||||
* required number of points. The input winding is freed.
|
||||
*/
|
||||
static winding_t *winding_shrink( winding_t *w )
|
||||
{
|
||||
winding_t *neww = winding_alloc( w->numpoints );
|
||||
memcpy( neww, w, (int)((winding_t *)0)->p[w->numpoints] );
|
||||
free_winding( w );
|
||||
|
||||
return neww;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
winding_for_plane
|
||||
====================
|
||||
*/
|
||||
static winding_t *winding_for_plane( const mplane_t *p )
|
||||
{
|
||||
vec3_t org, vright, vup;
|
||||
int i, axis;
|
||||
vec_t max, v;
|
||||
winding_t *w;
|
||||
|
||||
// find the major axis
|
||||
max = -BOGUS_RANGE;
|
||||
axis = -1;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
v = fabs( p->normal[i] );
|
||||
if( v > max )
|
||||
{
|
||||
axis = i;
|
||||
max = v;
|
||||
}
|
||||
}
|
||||
|
||||
VectorClear( vup );
|
||||
switch( axis )
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
vup[2] = 1;
|
||||
break;
|
||||
case 2:
|
||||
vup[0] = 1;
|
||||
break;
|
||||
default:
|
||||
Host_Error( "BaseWindingForPlane: no axis found\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
v = DotProduct( vup, p->normal );
|
||||
VectorMA( vup, -v, p->normal, vup );
|
||||
VectorNormalize( vup );
|
||||
VectorScale( p->normal, p->dist, org );
|
||||
CrossProduct( vup, p->normal, vright );
|
||||
VectorScale( vup, BOGUS_RANGE, vup );
|
||||
VectorScale( vright, BOGUS_RANGE, vright );
|
||||
|
||||
// project a really big axis aligned box onto the plane
|
||||
w = winding_alloc( 4 );
|
||||
memset( w->p, 0, sizeof( vec3_t ) * 4 );
|
||||
w->numpoints = 4;
|
||||
w->plane = p;
|
||||
|
||||
VectorSubtract( org, vright, w->p[0] );
|
||||
VectorAdd( w->p[0], vup, w->p[0] );
|
||||
VectorAdd( org, vright, w->p[1] );
|
||||
VectorAdd( w->p[1], vup, w->p[1] );
|
||||
VectorAdd( org, vright, w->p[2] );
|
||||
VectorSubtract( w->p[2], vup, w->p[2] );
|
||||
VectorSubtract( org, vright, w->p[3] );
|
||||
VectorSubtract( w->p[3], vup, w->p[3] );
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
/*
|
||||
* ===========================
|
||||
* Helper for for the clipping functions
|
||||
* (winding_clip, winding_split)
|
||||
* ===========================
|
||||
*/
|
||||
static void CalcSides( const winding_t *in, const mplane_t *split, int *sides, vec_t *dists, int counts[3], vec_t epsilon )
|
||||
{
|
||||
const vec_t *p;
|
||||
int i;
|
||||
|
||||
counts[0] = counts[1] = counts[2] = 0;
|
||||
|
||||
switch( split->type )
|
||||
{
|
||||
case PLANE_X:
|
||||
case PLANE_Y:
|
||||
case PLANE_Z:
|
||||
p = in->p[0] + split->type;
|
||||
for( i = 0; i < in->numpoints; i++, p += 3 )
|
||||
{
|
||||
const vec_t dot = *p - split->dist;
|
||||
|
||||
dists[i] = dot;
|
||||
if( dot > epsilon )
|
||||
sides[i] = SIDE_FRONT;
|
||||
else if( dot < -epsilon )
|
||||
sides[i] = SIDE_BACK;
|
||||
else sides[i] = SIDE_ON;
|
||||
counts[sides[i]]++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
p = in->p[0];
|
||||
for( i = 0; i < in->numpoints; i++, p += 3 )
|
||||
{
|
||||
const vec_t dot = DotProduct( split->normal, p ) - split->dist;
|
||||
|
||||
dists[i] = dot;
|
||||
if( dot > epsilon )
|
||||
sides[i] = SIDE_FRONT;
|
||||
else if( dot < -epsilon )
|
||||
sides[i] = SIDE_BACK;
|
||||
else sides[i] = SIDE_ON;
|
||||
counts[sides[i]]++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
sides[i] = sides[0];
|
||||
dists[i] = dists[0];
|
||||
}
|
||||
|
||||
static void PushToPlaneAxis( vec_t *v, const mplane_t *p )
|
||||
{
|
||||
const int t = p->type % 3;
|
||||
|
||||
v[t] = (p->dist - p->normal[(t + 1) % 3] * v[(t + 1) % 3] - p->normal[(t + 2) % 3] * v[(t + 2) % 3]) / p->normal[t];
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
winding_clip
|
||||
|
||||
Clips the winding to the plane, returning the new winding on 'side'.
|
||||
Frees the input winding.
|
||||
If keepon is true, an exactly on-plane winding will be saved, otherwise
|
||||
it will be clipped away.
|
||||
==================
|
||||
*/
|
||||
static winding_t *winding_clip( winding_t *in, const mplane_t *split, qboolean keepon, int side, vec_t epsilon )
|
||||
{
|
||||
vec_t *dists;
|
||||
int *sides;
|
||||
int counts[3];
|
||||
vec_t dot;
|
||||
int i, j;
|
||||
winding_t *neww;
|
||||
vec_t *p1, *p2, *mid;
|
||||
int maxpts;
|
||||
|
||||
dists = (vec_t *)malloc(( in->numpoints + 1 ) * sizeof( vec_t ));
|
||||
sides = (int *)malloc(( in->numpoints + 1 ) * sizeof( int ));
|
||||
CalcSides( in, split, sides, dists, counts, epsilon );
|
||||
|
||||
if( keepon && !counts[SIDE_FRONT] && !counts[SIDE_BACK] )
|
||||
{
|
||||
neww = in;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if( !counts[side] )
|
||||
{
|
||||
free_winding( in );
|
||||
neww = NULL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if( !counts[side ^ 1] )
|
||||
{
|
||||
neww = in;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
maxpts = in->numpoints + 4;
|
||||
neww = winding_alloc( maxpts );
|
||||
neww->numpoints = 0;
|
||||
neww->plane = in->plane;
|
||||
|
||||
for( i = 0; i < in->numpoints; i++ )
|
||||
{
|
||||
p1 = in->p[i];
|
||||
|
||||
if( sides[i] == SIDE_ON )
|
||||
{
|
||||
VectorCopy( p1, neww->p[neww->numpoints] );
|
||||
neww->numpoints++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( sides[i] == side )
|
||||
{
|
||||
VectorCopy( p1, neww->p[neww->numpoints] );
|
||||
neww->numpoints++;
|
||||
}
|
||||
|
||||
if( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] )
|
||||
continue;
|
||||
|
||||
// generate a split point
|
||||
p2 = in->p[(i + 1) % in->numpoints];
|
||||
mid = neww->p[neww->numpoints++];
|
||||
|
||||
dot = dists[i] / (dists[i] - dists[i + 1]);
|
||||
for( j = 0; j < 3; j++ )
|
||||
{
|
||||
// avoid round off error when possible
|
||||
if( in->plane->normal[j] == 1.0 )
|
||||
mid[j] = in->plane->dist;
|
||||
else if( in->plane->normal[j] == -1.0 )
|
||||
mid[j] = -in->plane->dist;
|
||||
else if( split->normal[j] == 1.0 )
|
||||
mid[j] = split->dist;
|
||||
else if( split->normal[j] == -1.0 )
|
||||
mid[j] = -split->dist;
|
||||
else mid[j] = p1[j] + dot * (p2[j] - p1[j]);
|
||||
}
|
||||
|
||||
if( in->plane->type < 3 )
|
||||
PushToPlaneAxis( mid, in->plane );
|
||||
}
|
||||
|
||||
// free the original winding
|
||||
free_winding( in );
|
||||
|
||||
// Shrink the winding back to just what it needs...
|
||||
neww = winding_shrink(neww);
|
||||
out_free:
|
||||
free( dists );
|
||||
free( sides );
|
||||
|
||||
return neww;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
winding_split
|
||||
|
||||
Splits a winding by a plane, producing one or two windings. The
|
||||
original winding is not damaged or freed. If only on one side, the
|
||||
returned winding will be the input winding. If on both sides, two
|
||||
new windings will be created.
|
||||
==================
|
||||
*/
|
||||
static void winding_split( winding_t *in, const mplane_t *split, winding_t **pfront, winding_t **pback )
|
||||
{
|
||||
vec_t *dists;
|
||||
int *sides;
|
||||
int counts[3];
|
||||
vec_t dot;
|
||||
int i, j;
|
||||
winding_t *front, *back;
|
||||
vec_t *p1, *p2, *mid;
|
||||
int maxpts;
|
||||
|
||||
dists = (vec_t *)malloc(( in->numpoints + 1 ) * sizeof( vec_t ));
|
||||
sides = (int *)malloc(( in->numpoints + 1 ) * sizeof( int ));
|
||||
CalcSides(in, split, sides, dists, counts, 0.04f );
|
||||
|
||||
if( !counts[0] && !counts[1] )
|
||||
{
|
||||
// winding on the split plane - return copies on both sides
|
||||
*pfront = winding_copy( in );
|
||||
*pback = winding_copy( in );
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if( !counts[0] )
|
||||
{
|
||||
*pfront = NULL;
|
||||
*pback = in;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if( !counts[1] )
|
||||
{
|
||||
*pfront = in;
|
||||
*pback = NULL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
maxpts = in->numpoints + 4;
|
||||
front = winding_alloc( maxpts );
|
||||
front->numpoints = 0;
|
||||
front->plane = in->plane;
|
||||
back = winding_alloc( maxpts );
|
||||
back->numpoints = 0;
|
||||
back->plane = in->plane;
|
||||
|
||||
for( i = 0; i < in->numpoints; i++ )
|
||||
{
|
||||
p1 = in->p[i];
|
||||
|
||||
if( sides[i] == SIDE_ON )
|
||||
{
|
||||
VectorCopy( p1, front->p[front->numpoints] );
|
||||
VectorCopy( p1, back->p[back->numpoints] );
|
||||
front->numpoints++;
|
||||
back->numpoints++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( sides[i] == SIDE_FRONT )
|
||||
{
|
||||
VectorCopy( p1, front->p[front->numpoints] );
|
||||
front->numpoints++;
|
||||
}
|
||||
else if( sides[i] == SIDE_BACK )
|
||||
{
|
||||
VectorCopy( p1, back->p[back->numpoints] );
|
||||
back->numpoints++;
|
||||
}
|
||||
|
||||
if( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] )
|
||||
continue;
|
||||
|
||||
// generate a split point
|
||||
p2 = in->p[(i + 1) % in->numpoints];
|
||||
mid = front->p[front->numpoints++];
|
||||
|
||||
dot = dists[i] / (dists[i] - dists[i + 1]);
|
||||
for( j = 0; j < 3; j++ )
|
||||
{
|
||||
// avoid round off error when possible
|
||||
if( in->plane->normal[j] == 1.0 )
|
||||
mid[j] = in->plane->dist;
|
||||
else if( in->plane->normal[j] == -1.0 )
|
||||
mid[j] = -in->plane->dist;
|
||||
else if( split->normal[j] == 1.0 )
|
||||
mid[j] = split->dist;
|
||||
else if( split->normal[j] == -1.0 )
|
||||
mid[j] = -split->dist;
|
||||
else mid[j] = p1[j] + dot * (p2[j] - p1[j]);
|
||||
}
|
||||
|
||||
if( in->plane->type < 3 )
|
||||
PushToPlaneAxis( mid, in->plane );
|
||||
VectorCopy( mid, back->p[back->numpoints] );
|
||||
back->numpoints++;
|
||||
}
|
||||
|
||||
*pfront = winding_shrink( front );
|
||||
*pback = winding_shrink( back );
|
||||
out_free:
|
||||
free( dists );
|
||||
free( sides );
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* This is a stack of the clipnodes we have traversed
|
||||
* "sides" indicates which side we went down each time
|
||||
*/
|
||||
static mclipnode_t *node_stack[MAX_CLIPNODE_DEPTH];
|
||||
static int side_stack[MAX_CLIPNODE_DEPTH];
|
||||
static uint node_stack_depth;
|
||||
|
||||
static void push_node( mclipnode_t *node, int side )
|
||||
{
|
||||
if( node_stack_depth == MAX_CLIPNODE_DEPTH )
|
||||
Host_Error( "node stack overflow\n" );
|
||||
|
||||
node_stack[node_stack_depth] = node;
|
||||
side_stack[node_stack_depth] = side;
|
||||
node_stack_depth++;
|
||||
}
|
||||
|
||||
static void pop_node( void )
|
||||
{
|
||||
if( !node_stack_depth )
|
||||
Host_Error( "node stack underflow\n" );
|
||||
node_stack_depth--;
|
||||
}
|
||||
|
||||
static void free_hull_polys( hullnode_t *hull_polys )
|
||||
{
|
||||
winding_t *w, *next;
|
||||
|
||||
list_for_each_entry_safe( w, next, hull_polys, chain )
|
||||
{
|
||||
list_del( &w->chain );
|
||||
free_winding( w );
|
||||
}
|
||||
}
|
||||
|
||||
static void hull_windings_r( hull_t *hull, mclipnode_t *node, hullnode_t *polys, hull_model_t *model );
|
||||
|
||||
static void do_hull_recursion( hull_t *hull, mclipnode_t *node, int side, hullnode_t *polys, hull_model_t *model )
|
||||
{
|
||||
winding_t *w, *next;
|
||||
|
||||
if( node->children[side] >= 0 )
|
||||
{
|
||||
mclipnode_t *child = hull->clipnodes + node->children[side];
|
||||
push_node( node, side );
|
||||
hull_windings_r( hull, child, polys, model );
|
||||
pop_node();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( node->children[side] )
|
||||
{
|
||||
case CONTENTS_EMPTY:
|
||||
case CONTENTS_WATER:
|
||||
case CONTENTS_SLIME:
|
||||
case CONTENTS_LAVA:
|
||||
list_for_each_entry_safe( w, next, polys, chain )
|
||||
{
|
||||
list_del( &w->chain );
|
||||
list_add( &w->chain, &model->polys );
|
||||
}
|
||||
break;
|
||||
case CONTENTS_SOLID:
|
||||
case CONTENTS_SKY:
|
||||
// throw away polys...
|
||||
list_for_each_entry_safe( w, next, polys, chain )
|
||||
{
|
||||
if( w->pair )
|
||||
w->pair->pair = NULL;
|
||||
list_del( &w->chain );
|
||||
free_winding( w );
|
||||
model->num_polys--;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Host_Error( "bad contents: %i\n", node->children[side] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void hull_windings_r( hull_t *hull, mclipnode_t *node, hullnode_t *polys, hull_model_t *model )
|
||||
{
|
||||
mplane_t *plane = hull->planes + node->planenum;
|
||||
hullnode_t frontlist = LIST_HEAD_INIT( frontlist );
|
||||
hullnode_t backlist = LIST_HEAD_INIT( backlist );
|
||||
winding_t *w, *next, *front, *back;
|
||||
int i;
|
||||
|
||||
list_for_each_entry_safe( w, next, polys, chain )
|
||||
{
|
||||
// PARANIOA - PAIR CHECK
|
||||
ASSERT( !w->pair || w->pair->pair == w );
|
||||
|
||||
list_del( &w->chain );
|
||||
winding_split( w, plane, &front, &back );
|
||||
if( front ) list_add( &front->chain, &frontlist );
|
||||
if( back ) list_add( &back->chain, &backlist );
|
||||
|
||||
if( front && back )
|
||||
{
|
||||
if( w->pair )
|
||||
{
|
||||
// split the paired poly, preserve pairing
|
||||
winding_t *front2, *back2;
|
||||
|
||||
winding_split( w->pair, plane, &front2, &back2 );
|
||||
|
||||
front2->pair = front;
|
||||
front->pair = front2;
|
||||
back2->pair = back;
|
||||
back->pair = back2;
|
||||
|
||||
list_add( &front2->chain, &w->pair->chain );
|
||||
list_add( &back2->chain, &w->pair->chain );
|
||||
list_del( &w->pair->chain );
|
||||
free_winding( w->pair );
|
||||
model->num_polys++;
|
||||
}
|
||||
else
|
||||
{
|
||||
front->pair = NULL;
|
||||
back->pair = NULL;
|
||||
}
|
||||
|
||||
model->num_polys++;
|
||||
free_winding( w );
|
||||
}
|
||||
}
|
||||
|
||||
w = winding_for_plane(plane);
|
||||
|
||||
for( i = 0; w && i < node_stack_depth; i++ )
|
||||
{
|
||||
mplane_t *p = hull->planes + node_stack[i]->planenum;
|
||||
w = winding_clip( w, p, false, side_stack[i], 0.00001 );
|
||||
}
|
||||
|
||||
if( w )
|
||||
{
|
||||
winding_t *tmp = winding_copy( w );
|
||||
winding_reverse( tmp );
|
||||
|
||||
w->pair = tmp;
|
||||
tmp->pair = w;
|
||||
|
||||
list_add( &w->chain, &frontlist );
|
||||
list_add( &tmp->chain, &backlist );
|
||||
|
||||
// PARANIOA - PAIR CHECK
|
||||
ASSERT( !w->pair || w->pair->pair == w );
|
||||
model->num_polys += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf( S_WARN "new winding was clipped away!\n" );
|
||||
}
|
||||
|
||||
do_hull_recursion( hull, node, 0, &frontlist, model );
|
||||
do_hull_recursion( hull, node, 1, &backlist, model );
|
||||
}
|
||||
|
||||
static void remove_paired_polys( hull_model_t *model )
|
||||
{
|
||||
winding_t *w, *next;
|
||||
|
||||
list_for_each_entry_safe( w, next, &model->polys, chain )
|
||||
{
|
||||
if( w->pair )
|
||||
{
|
||||
list_del( &w->chain );
|
||||
free_winding( w );
|
||||
model->num_polys--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void make_hull_windings( hull_t *hull, hull_model_t *model )
|
||||
{
|
||||
hullnode_t head = LIST_HEAD_INIT( head );
|
||||
|
||||
Con_Reportf( "%i clipnodes...\n", hull->lastclipnode - hull->firstclipnode );
|
||||
|
||||
node_stack_depth = 0;
|
||||
model->num_polys = 0;
|
||||
|
||||
if( hull->planes != NULL )
|
||||
{
|
||||
hull_windings_r( hull, hull->clipnodes + hull->firstclipnode, &head, model );
|
||||
remove_paired_polys( model );
|
||||
}
|
||||
Con_Reportf( "%i hull polys\n", model->num_polys );
|
||||
}
|
||||
|
||||
void Mod_InitDebugHulls( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
world.hull_models = Mem_Calloc( loadmodel->mempool, sizeof( hull_model_t ) * loadmodel->numsubmodels );
|
||||
world.num_hull_models = loadmodel->numsubmodels;
|
||||
|
||||
// initialize list
|
||||
for( i = 0; i < world.num_hull_models; i++ )
|
||||
{
|
||||
hullnode_t *poly = &world.hull_models[i].polys;
|
||||
poly->next = poly;
|
||||
poly->prev = poly;
|
||||
}
|
||||
}
|
||||
|
||||
void Mod_CreatePolygonsForHull( int hullnum )
|
||||
{
|
||||
model_t *mod = cl.worldmodel;
|
||||
double start, end;
|
||||
char name[8];
|
||||
int i;
|
||||
|
||||
if( hullnum < 1 || hullnum > 3 )
|
||||
return;
|
||||
|
||||
Con_Printf( "generating polygons for hull %u...\n", hullnum );
|
||||
start = Sys_DoubleTime();
|
||||
|
||||
// rebuild hulls list
|
||||
for( i = 0; i < world.num_hull_models; i++ )
|
||||
{
|
||||
hull_model_t *model = &world.hull_models[i];
|
||||
free_hull_polys( &model->polys );
|
||||
make_hull_windings( &mod->hulls[hullnum], model );
|
||||
Q_snprintf( name, sizeof( name ), "*%i", i + 1 );
|
||||
mod = Mod_FindName( name, false );
|
||||
}
|
||||
end = Sys_DoubleTime();
|
||||
Con_Printf( "build time %.3f secs\n", end - start );
|
||||
}
|
||||
|
||||
void Mod_ReleaseHullPolygons( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
// release ploygons
|
||||
for( i = 0; i < world.num_hull_models; i++ )
|
||||
{
|
||||
hull_model_t *model = &world.hull_models[i];
|
||||
free_hull_polys( &model->polys );
|
||||
}
|
||||
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 );
|
||||
}
|
|
@ -33,7 +33,7 @@ GNU General Public License for more details.
|
|||
|
||||
#define MAXDLY (STEREODLY + 1)
|
||||
#define MAXLP 10
|
||||
#define MAXPRESETS ARRAYSIZE( rgsxpre )
|
||||
#define MAXPRESETS 29
|
||||
|
||||
typedef struct sx_preset_s
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ typedef struct dly_s
|
|||
int *lpdelayline;
|
||||
} dly_t;
|
||||
|
||||
const sx_preset_t rgsxpre[] =
|
||||
const sx_preset_t rgsxpre[MAXPRESETS] =
|
||||
{
|
||||
// -------reverb-------- -------delay--------
|
||||
// lp mod size refl rvblp delay feedback dlylp left
|
||||
|
@ -193,7 +193,7 @@ void SX_Init( void )
|
|||
sxmod1cur = sxmod1 = 350 * ( idsp_dma_speed / SOUND_11k );
|
||||
sxmod2cur = sxmod2 = 450 * ( idsp_dma_speed / SOUND_11k );
|
||||
|
||||
dsp_off = Cvar_Get( "dsp_off", "0", 0, "disable DSP processing" );
|
||||
dsp_off = Cvar_Get( "dsp_off", "0", FCVAR_ARCHIVE, "disable DSP processing" );
|
||||
roomwater_type = Cvar_Get( "waterroom_type", "14", 0, "water room type" );
|
||||
room_type = Cvar_Get( "room_type", "0", 0, "current room type preset" );
|
||||
|
||||
|
@ -273,7 +273,7 @@ int DLY_Init( int idelay, float delay )
|
|||
|
||||
cur = &rgsxdly[idelay];
|
||||
cur->cdelaysamplesmax = ((int)(delay * idsp_dma_speed) << sxhires) + 1;
|
||||
cur->lpdelayline = (int *)Z_Malloc( cur->cdelaysamplesmax * sizeof( int ));
|
||||
cur->lpdelayline = (int *)Z_Calloc( cur->cdelaysamplesmax * sizeof( int ));
|
||||
cur->xfade = 0;
|
||||
|
||||
// init modulation
|
||||
|
@ -609,16 +609,15 @@ int RVB_DoReverbForOneDly( dly_t *dly, const int vlr, const portable_samplepair_
|
|||
if( dly->xfade || delay || samplepair->left || samplepair->right )
|
||||
{
|
||||
// modulate delay rate
|
||||
if( !dly->mod )
|
||||
if( !dly->xfade && !dly->modcur && dly->mod )
|
||||
{
|
||||
dly->idelayoutputxf = dly->idelayoutput + ((COM_RandomLong( 0, 255 ) * delay) >> 9 );
|
||||
|
||||
if( dly->idelayoutputxf >= dly->cdelaysamplesmax )
|
||||
dly->idelayoutputxf -= dly->cdelaysamplesmax;
|
||||
|
||||
dly->xfade = REVERB_XFADE;
|
||||
//dly->xfade = 32;
|
||||
}
|
||||
|
||||
dly->idelayoutputxf %= dly->cdelaysamplesmax;
|
||||
|
||||
if( dly->xfade )
|
||||
{
|
||||
samplexf = (dly->lpdelayline[dly->idelayoutputxf] * (REVERB_XFADE - dly->xfade)) / REVERB_XFADE;
|
||||
|
@ -819,6 +818,9 @@ void CheckNewDspPresets( void )
|
|||
idsp_room = roomwater_type->value;
|
||||
else idsp_room = room_type->value;
|
||||
|
||||
// don't pass invalid presets
|
||||
idsp_room = bound( 0, idsp_room, MAXPRESETS - 1 );
|
||||
|
||||
if( FBitSet( hisound->flags, FCVAR_CHANGED ))
|
||||
{
|
||||
sxhires = hisound->value;
|
||||
|
|
|
@ -44,7 +44,7 @@ void S_SoundList_f( void )
|
|||
|
||||
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++ )
|
||||
{
|
||||
if( !sfx->servercount )
|
||||
if( !sfx->name[0] )
|
||||
continue;
|
||||
|
||||
sc = sfx->cache;
|
||||
|
@ -54,7 +54,9 @@ void S_SoundList_f( void )
|
|||
|
||||
if( sc->loopStart >= 0 ) Con_Printf( "L" );
|
||||
else Con_Printf( " " );
|
||||
Con_Printf( " (%2db) %s : sound/%s\n", sc->width * 8, Q_memprint( sc->size ), sfx->name );
|
||||
if( sfx->name[0] == '*' )
|
||||
Con_Printf( " (%2db) %s : %s\n", sc->width * 8, Q_memprint( sc->size ), sfx->name );
|
||||
else Con_Printf( " (%2db) %s : %s%s\n", sc->width * 8, Q_memprint( sc->size ), DEFAULT_SOUNDPATH, sfx->name );
|
||||
totalSfx++;
|
||||
}
|
||||
}
|
||||
|
@ -104,7 +106,7 @@ static wavdata_t *S_CreateDefaultSound( void )
|
|||
{
|
||||
wavdata_t *sc;
|
||||
|
||||
sc = Mem_Alloc( sndpool, sizeof( wavdata_t ));
|
||||
sc = Mem_Calloc( sndpool, sizeof( wavdata_t ));
|
||||
|
||||
sc->width = 2;
|
||||
sc->channels = 1;
|
||||
|
@ -112,7 +114,7 @@ static wavdata_t *S_CreateDefaultSound( void )
|
|||
sc->rate = SOUND_DMA_SPEED;
|
||||
sc->samples = SOUND_DMA_SPEED;
|
||||
sc->size = sc->samples * sc->width * sc->channels;
|
||||
sc->buffer = Mem_Alloc( sndpool, sc->size );
|
||||
sc->buffer = Mem_Calloc( sndpool, sc->size );
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
@ -127,8 +129,15 @@ wavdata_t *S_LoadSound( sfx_t *sfx )
|
|||
wavdata_t *sc = NULL;
|
||||
|
||||
if( !sfx ) return NULL;
|
||||
if( sfx->cache ) return sfx->cache; // see if still in memory
|
||||
|
||||
// see if still in memory
|
||||
if( sfx->cache )
|
||||
return sfx->cache;
|
||||
|
||||
if( !COM_CheckString( sfx->name ))
|
||||
return NULL;
|
||||
|
||||
// load it from disk
|
||||
if( Q_stricmp( sfx->name, "*default" ))
|
||||
{
|
||||
// load it from disk
|
||||
|
@ -169,11 +178,8 @@ sfx_t *S_FindName( const char *pname, int *pfInCache )
|
|||
if( !COM_CheckString( pname ) || !dma.initialized )
|
||||
return NULL;
|
||||
|
||||
if( Q_strlen( pname ) >= MAX_STRING )
|
||||
{
|
||||
MsgDev( D_ERROR, "S_FindSound: sound name too long: %s", pname );
|
||||
if( Q_strlen( pname ) >= sizeof( sfx->name ))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Q_strncpy( name, pname, sizeof( name ));
|
||||
COM_FixSlashes( name );
|
||||
|
@ -202,10 +208,7 @@ sfx_t *S_FindName( const char *pname, int *pfInCache )
|
|||
if( i == s_numSfx )
|
||||
{
|
||||
if( s_numSfx == MAX_SFX )
|
||||
{
|
||||
MsgDev( D_ERROR, "S_FindName: MAX_SFX limit exceeded\n" );
|
||||
return NULL;
|
||||
}
|
||||
s_numSfx++;
|
||||
}
|
||||
|
||||
|
@ -233,7 +236,8 @@ void S_FreeSound( sfx_t *sfx )
|
|||
sfx_t *hashSfx;
|
||||
sfx_t **prev;
|
||||
|
||||
if( !sfx || !sfx->name[0] ) return;
|
||||
if( !sfx || !sfx->name[0] )
|
||||
return;
|
||||
|
||||
// de-link it from the hash tree
|
||||
prev = &s_sfxHashList[sfx->hashValue];
|
||||
|
@ -251,7 +255,8 @@ void S_FreeSound( sfx_t *sfx )
|
|||
prev = &hashSfx->hashNext;
|
||||
}
|
||||
|
||||
if( sfx->cache ) FS_FreeSound( sfx->cache );
|
||||
if( sfx->cache )
|
||||
FS_FreeSound( sfx->cache );
|
||||
memset( sfx, 0, sizeof( *sfx ));
|
||||
}
|
||||
|
||||
|
@ -266,11 +271,6 @@ void S_BeginRegistration( void )
|
|||
int i;
|
||||
|
||||
s_registration_sequence++;
|
||||
s_registering = true;
|
||||
|
||||
// create unused 0-entry
|
||||
S_RegisterSound( "*default" );
|
||||
|
||||
snd_ambient = false;
|
||||
|
||||
// check for automatic ambient sounds
|
||||
|
@ -279,11 +279,11 @@ void S_BeginRegistration( void )
|
|||
if( !GI->ambientsound[i][0] )
|
||||
continue; // empty slot
|
||||
|
||||
if( !ambient_sfx[i] )
|
||||
MsgDev( D_NOTE, "Loading ambient[%i]: ^2%s^7\n", i, GI->ambientsound[i] );
|
||||
ambient_sfx[i] = S_RegisterSound( GI->ambientsound[i] );
|
||||
if( ambient_sfx[i] ) snd_ambient = true; // allow auto-ambients
|
||||
}
|
||||
|
||||
s_registering = true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -303,7 +303,9 @@ void S_EndRegistration( void )
|
|||
// free any sounds not from this registration sequence
|
||||
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++ )
|
||||
{
|
||||
if( !sfx->name[0] ) continue;
|
||||
if( !sfx->name[0] || !Q_stricmp( sfx->name, "*default" ))
|
||||
continue; // don't release default sound
|
||||
|
||||
if( sfx->servercount != s_registration_sequence )
|
||||
S_FreeSound( sfx ); // don't need this sound
|
||||
}
|
||||
|
@ -311,7 +313,8 @@ void S_EndRegistration( void )
|
|||
// load everything in
|
||||
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++ )
|
||||
{
|
||||
if( !sfx->name[0] ) continue;
|
||||
if( !sfx->name[0] )
|
||||
continue;
|
||||
S_LoadSound( sfx );
|
||||
}
|
||||
s_registering = false;
|
||||
|
@ -351,23 +354,35 @@ sound_t S_RegisterSound( const char *name )
|
|||
|
||||
sfx_t *S_GetSfxByHandle( sound_t handle )
|
||||
{
|
||||
if( handle == -1 || !dma.initialized )
|
||||
if( !dma.initialized )
|
||||
return NULL;
|
||||
|
||||
if( handle == SENTENCE_INDEX )
|
||||
{
|
||||
// create new sfx
|
||||
if( handle == SENTENCE_INDEX )
|
||||
return S_FindName( s_sentenceImmediateName, NULL );
|
||||
}
|
||||
|
||||
if( handle < 0 || handle >= s_numSfx )
|
||||
{
|
||||
MsgDev( D_ERROR, "S_GetSfxByHandle: handle %i out of range (%i)\n", handle, s_numSfx );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &s_knownSfx[handle];
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_InitSounds
|
||||
=================
|
||||
*/
|
||||
void S_InitSounds( void )
|
||||
{
|
||||
// create unused 0-entry
|
||||
Q_strncpy( s_knownSfx->name, "*default", MAX_QPATH );
|
||||
s_knownSfx->hashValue = COM_HashKey( s_knownSfx->name, MAX_SFX_HASH );
|
||||
s_knownSfx->hashNext = s_sfxHashList[s_knownSfx->hashValue];
|
||||
s_sfxHashList[s_knownSfx->hashValue] = s_knownSfx;
|
||||
s_knownSfx->cache = S_CreateDefaultSound();
|
||||
s_numSfx = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_FreeSounds
|
||||
|
|
|
@ -19,6 +19,7 @@ GNU General Public License for more details.
|
|||
#include "con_nprint.h"
|
||||
#include "gl_local.h"
|
||||
#include "pm_local.h"
|
||||
#include "platform/platform.h"
|
||||
|
||||
#define SND_CLIP_DISTANCE 1000.0f
|
||||
|
||||
|
@ -275,6 +276,28 @@ void SND_ChannelTraceReset( void )
|
|||
channels[i].bTraced = false;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SND_FStreamIsPlaying
|
||||
|
||||
Select a channel from the dynamic channel allocation area. For the given entity,
|
||||
override any other sound playing on the same channel (see code comments below for
|
||||
exceptions).
|
||||
=================
|
||||
*/
|
||||
qboolean SND_FStreamIsPlaying( sfx_t *sfx )
|
||||
{
|
||||
int ch_idx;
|
||||
|
||||
for( ch_idx = NUM_AMBIENTS; ch_idx < MAX_DYNAMIC_CHANNELS; ch_idx++ )
|
||||
{
|
||||
if( channels[ch_idx].sfx == sfx )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SND_PickDynamicChannel
|
||||
|
@ -296,6 +319,13 @@ channel_t *SND_PickDynamicChannel( int entnum, int channel, sfx_t *sfx, qboolean
|
|||
life_left = 0x7fffffff;
|
||||
if( ignore ) *ignore = false;
|
||||
|
||||
if( channel == CHAN_STREAM && SND_FStreamIsPlaying( sfx ))
|
||||
{
|
||||
if( ignore )
|
||||
*ignore = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for( ch_idx = NUM_AMBIENTS; ch_idx < MAX_DYNAMIC_CHANNELS; ch_idx++ )
|
||||
{
|
||||
channel_t *ch = &channels[ch_idx];
|
||||
|
@ -392,7 +422,7 @@ channel_t *SND_PickStaticChannel( const vec3_t pos, sfx_t *sfx )
|
|||
// no empty slots, alloc a new static sound channel
|
||||
if( total_channels == MAX_CHANNELS )
|
||||
{
|
||||
MsgDev( D_ERROR, "S_PickStaticChannel: no free channels\n" );
|
||||
Con_DPrintf( S_ERROR "S_PickStaticChannel: no free channels\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -896,14 +926,11 @@ 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( pitch == 0 )
|
||||
{
|
||||
MsgDev( D_WARN, "S_StartSound: ( %s ) ignored, called with pitch 0\n", sfx->name );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !pos ) pos = RI.vieworg;
|
||||
|
||||
if( chan == CHAN_STREAM )
|
||||
SetBits( flags, SND_STOP_LOOPING );
|
||||
|
||||
// pick a channel to play on
|
||||
if( chan == CHAN_STATIC ) target_chan = SND_PickStaticChannel( pos, sfx );
|
||||
else target_chan = SND_PickDynamicChannel( ent, chan, sfx, &bIgnore );
|
||||
|
@ -1024,12 +1051,6 @@ void S_RestoreSound( const vec3_t pos, int ent, int chan, sound_t handle, float
|
|||
vol = bound( 0, fvol * 255, 255 );
|
||||
if( pitch <= 1 ) pitch = PITCH_NORM; // Invasion issues
|
||||
|
||||
if( pitch == 0 )
|
||||
{
|
||||
MsgDev( D_WARN, "S_RestoreSound: ( %s ) ignored, called with pitch 0\n", sfx->name );
|
||||
return;
|
||||
}
|
||||
|
||||
// pick a channel to play on
|
||||
if( chan == CHAN_STATIC ) target_chan = SND_PickStaticChannel( pos, sfx );
|
||||
else target_chan = SND_PickDynamicChannel( ent, chan, sfx, &bIgnore );
|
||||
|
@ -1158,12 +1179,6 @@ void S_AmbientSound( const vec3_t pos, int ent, sound_t handle, float fvol, floa
|
|||
if( flags & SND_STOP ) return;
|
||||
}
|
||||
|
||||
if( pitch == 0 )
|
||||
{
|
||||
MsgDev( D_WARN, "S_AmbientSound: ( %s ) ignored, called with pitch 0\n", sfx->name );
|
||||
return;
|
||||
}
|
||||
|
||||
// pick a channel to play on from the static area
|
||||
ch = SND_PickStaticChannel( pos, sfx );
|
||||
if( !ch ) return;
|
||||
|
@ -1303,7 +1318,7 @@ int S_GetCurrentDynamicSounds( soundlist_t *pout, int size )
|
|||
|
||||
looped = ( channels[i].use_loop && channels[i].sfx->cache->loopStart != -1 );
|
||||
|
||||
if( channels[i].entchannel == CHAN_STATIC && looped && !FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
if( channels[i].entchannel == CHAN_STATIC && looped && !Host_IsQuakeCompatible())
|
||||
continue; // never serialize static looped sounds. It will be restoring in game code
|
||||
|
||||
if( channels[i].isSentence && channels[i].name[0] )
|
||||
|
@ -1380,7 +1395,13 @@ void S_UpdateAmbientSounds( void )
|
|||
chan = &channels[ambient_channel];
|
||||
chan->sfx = S_GetSfxByHandle( ambient_sfx[ambient_channel] );
|
||||
|
||||
if( !chan->sfx ) continue;
|
||||
// ambient is unused
|
||||
if( !chan->sfx )
|
||||
{
|
||||
chan->rightvol = 0;
|
||||
chan->leftvol = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
vol = s_ambient_level->value * leaf->ambient_sound_level[ambient_channel];
|
||||
if( vol < 0 ) vol = 0;
|
||||
|
@ -1459,7 +1480,7 @@ rawchan_t *S_FindRawChannel( int entnum, qboolean create )
|
|||
if( !raw_channels[best] )
|
||||
{
|
||||
raw_samples = MAX_RAW_SAMPLES;
|
||||
raw_channels[best] = Mem_Alloc( sndpool, sizeof( *ch ) + sizeof( portable_samplepair_t ) * ( raw_samples - 1 ));
|
||||
raw_channels[best] = Mem_Calloc( sndpool, sizeof( *ch ) + sizeof( portable_samplepair_t ) * ( raw_samples - 1 ));
|
||||
}
|
||||
|
||||
ch = raw_channels[best];
|
||||
|
@ -1564,7 +1585,7 @@ S_RawSamples
|
|||
*/
|
||||
void S_RawSamples( uint samples, uint rate, word width, word channels, const byte *data, int entnum )
|
||||
{
|
||||
int snd_vol;
|
||||
int snd_vol = 128;
|
||||
|
||||
if( entnum < 0 ) snd_vol = 256; // bg track or movie track
|
||||
if( snd_vol < 0 ) snd_vol = 0; // fixup negative values
|
||||
|
@ -1577,9 +1598,17 @@ void S_RawSamples( uint samples, uint rate, word width, word channels, const byt
|
|||
S_PositionedRawSamples
|
||||
===================
|
||||
*/
|
||||
static void S_PositionedRawSamples( int entnum, float fvol, float attn, uint samples, uint rate, word width, word channels, const byte *data )
|
||||
void S_StreamAviSamples( void *Avi, int entnum, float fvol, float attn, float synctime )
|
||||
{
|
||||
rawchan_t *ch;
|
||||
int bufferSamples;
|
||||
int fileSamples;
|
||||
byte raw[MAX_RAW_SAMPLES];
|
||||
float duration = 0.0f;
|
||||
int r, fileBytes;
|
||||
rawchan_t *ch = NULL;
|
||||
|
||||
if( !dma.initialized || s_listener.paused || !CL_IsInGame( ))
|
||||
return;
|
||||
|
||||
if( entnum < 0 || entnum >= GI->max_edicts )
|
||||
return;
|
||||
|
@ -1587,9 +1616,61 @@ static void S_PositionedRawSamples( int entnum, float fvol, float attn, uint sam
|
|||
if( !( ch = S_FindRawChannel( entnum, true )))
|
||||
return;
|
||||
|
||||
if( ch->sound_info.rate == 0 )
|
||||
{
|
||||
if( !AVI_GetAudioInfo( Avi, &ch->sound_info ))
|
||||
return; // no audiotrack
|
||||
}
|
||||
|
||||
ch->master_vol = bound( 0, fvol * 255, 255 );
|
||||
ch->dist_mult = (attn / SND_CLIP_DISTANCE);
|
||||
ch->s_rawend = S_RawSamplesStereo( ch->rawsamples, ch->s_rawend, ch->max_samples, samples, rate, width, channels, data );
|
||||
|
||||
// see how many samples should be copied into the raw buffer
|
||||
if( ch->s_rawend < soundtime )
|
||||
ch->s_rawend = soundtime;
|
||||
|
||||
// position is changed, synchronization is lost etc
|
||||
if( fabs( ch->oldtime - synctime ) > s_mixahead->value )
|
||||
ch->sound_info.loopStart = AVI_TimeToSoundPosition( Avi, synctime * 1000 );
|
||||
ch->oldtime = synctime; // keep actual time
|
||||
|
||||
while( ch->s_rawend < soundtime + ch->max_samples )
|
||||
{
|
||||
wavdata_t *info = &ch->sound_info;
|
||||
|
||||
bufferSamples = ch->max_samples - (ch->s_rawend - soundtime);
|
||||
|
||||
// decide how much data needs to be read from the file
|
||||
fileSamples = bufferSamples * ((float)info->rate / SOUND_DMA_SPEED );
|
||||
if( fileSamples <= 1 ) return; // no more samples need
|
||||
|
||||
// our max buffer size
|
||||
fileBytes = fileSamples * ( info->width * info->channels );
|
||||
|
||||
if( fileBytes > sizeof( raw ))
|
||||
{
|
||||
fileBytes = sizeof( raw );
|
||||
fileSamples = fileBytes / ( info->width * info->channels );
|
||||
}
|
||||
|
||||
// read audio stream
|
||||
r = AVI_GetAudioChunk( Avi, raw, info->loopStart, fileBytes );
|
||||
info->loopStart += r; // advance play position
|
||||
|
||||
if( r < fileBytes )
|
||||
{
|
||||
fileBytes = r;
|
||||
fileSamples = r / ( info->width * info->channels );
|
||||
}
|
||||
|
||||
if( r > 0 )
|
||||
{
|
||||
// add to raw buffer
|
||||
ch->s_rawend = S_RawSamplesStereo( ch->rawsamples, ch->s_rawend, ch->max_samples,
|
||||
fileSamples, info->rate, info->width, info->channels, raw );
|
||||
}
|
||||
else break; // no more samples for this frame
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1665,6 +1746,7 @@ static void S_ClearRawChannels( void )
|
|||
|
||||
if( !ch ) continue;
|
||||
ch->s_rawend = 0;
|
||||
ch->oldtime = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1868,6 +1950,23 @@ void S_ExtraUpdate( void )
|
|||
S_UpdateChannels ();
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
S_UpdateFrame
|
||||
|
||||
update listener position
|
||||
============
|
||||
*/
|
||||
void S_UpdateFrame( struct ref_viewpass_s *rvp )
|
||||
{
|
||||
if( !FBitSet( rvp->flags, RF_DRAW_WORLD ) || FBitSet( rvp->flags, RF_ONLY_CLIENTDRAW ))
|
||||
return;
|
||||
|
||||
VectorCopy( rvp->vieworigin, s_listener.origin );
|
||||
AngleVectors( rvp->viewangles, s_listener.forward, s_listener.right, s_listener.up );
|
||||
s_listener.entnum = rvp->viewentity; // can be camera entity too
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
SND_UpdateSound
|
||||
|
@ -1892,17 +1991,13 @@ void SND_UpdateSound( void )
|
|||
// release raw-channels that no longer used more than 10 secs
|
||||
S_FreeIdleRawChannels();
|
||||
|
||||
s_listener.entnum = cl.viewentity; // can be camera entity too
|
||||
VectorCopy( cl.simvel, s_listener.velocity );
|
||||
s_listener.frametime = (cl.time - cl.oldtime);
|
||||
s_listener.waterlevel = cl.local.waterlevel;
|
||||
s_listener.active = CL_IsInGame();
|
||||
s_listener.inmenu = CL_IsInMenu();
|
||||
s_listener.paused = cl.paused;
|
||||
|
||||
VectorCopy( RI.vieworg, s_listener.origin );
|
||||
VectorCopy( cl.simvel, s_listener.velocity );
|
||||
AngleVectors( RI.viewangles, s_listener.forward, s_listener.right, s_listener.up );
|
||||
|
||||
if( cl.worldmodel != NULL )
|
||||
Mod_FatPVS( s_listener.origin, FATPHS_RADIUS, s_listener.pasbytes, world.visbytes, false, !s_phs->value );
|
||||
|
||||
|
@ -1963,7 +2058,7 @@ void SND_UpdateSound( void )
|
|||
S_SpatializeRawChannels();
|
||||
|
||||
// debugging output
|
||||
if( s_show->value )
|
||||
if( CVAR_TO_BOOL( s_show ))
|
||||
{
|
||||
info.color[0] = 1.0f;
|
||||
info.color[1] = 0.6f;
|
||||
|
@ -2019,6 +2114,23 @@ void S_Play_f( void )
|
|||
S_StartLocalSound( Cmd_Argv( 1 ), VOL_NORM, false );
|
||||
}
|
||||
|
||||
void S_Play2_f( void )
|
||||
{
|
||||
int i = 1;
|
||||
|
||||
if( Cmd_Argc() == 1 )
|
||||
{
|
||||
Con_Printf( S_USAGE "play2 <soundfile>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
while( i < Cmd_Argc( ))
|
||||
{
|
||||
S_StartLocalSound( Cmd_Argv( i ), VOL_NORM, true );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void S_PlayVol_f( void )
|
||||
{
|
||||
if( Cmd_Argc() == 1 )
|
||||
|
@ -2162,7 +2274,7 @@ qboolean S_Init( void )
|
|||
{
|
||||
if( Sys_CheckParm( "-nosound" ))
|
||||
{
|
||||
MsgDev( D_INFO, "Audio: Disabled\n" );
|
||||
Con_Printf( "Audio: Disabled\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2173,7 +2285,7 @@ qboolean S_Init( void )
|
|||
s_lerping = Cvar_Get( "s_lerping", "0", FCVAR_ARCHIVE, "apply interpolation to sound output" );
|
||||
s_ambient_level = Cvar_Get( "ambient_level", "0.3", FCVAR_ARCHIVE, "volume of environment noises (water and wind)" );
|
||||
s_ambient_fade = Cvar_Get( "ambient_fade", "1000", FCVAR_ARCHIVE, "rate of volume fading when client is moving" );
|
||||
s_combine_sounds = Cvar_Get( "s_combine_channels", "1", FCVAR_ARCHIVE, "combine channels with same sounds" );
|
||||
s_combine_sounds = Cvar_Get( "s_combine_channels", "0", FCVAR_ARCHIVE, "combine channels with same sounds" );
|
||||
snd_foliage_db_loss = Cvar_Get( "snd_foliage_db_loss", "4", 0, "foliage loss factor" );
|
||||
snd_gain_max = Cvar_Get( "snd_gain_max", "1", 0, "gain maximal threshold" );
|
||||
snd_gain_min = Cvar_Get( "snd_gain_min", "0.01", 0, "gain minimal threshold" );
|
||||
|
@ -2187,6 +2299,7 @@ qboolean S_Init( void )
|
|||
s_samplecount = Cvar_Get( "s_samplecount", "0", FCVAR_ARCHIVE, "sample count (0 for default value)" );
|
||||
|
||||
Cmd_AddCommand( "play", S_Play_f, "playing a specified sound file" );
|
||||
Cmd_AddCommand( "play2", S_Play2_f, "playing a group of specified sound files" ); // nehahra stuff
|
||||
Cmd_AddCommand( "playvol", S_PlayVol_f, "playing a specified sound file with specified volume" );
|
||||
Cmd_AddCommand( "stopsound", S_StopSound_f, "stop all sounds" );
|
||||
Cmd_AddCommand( "music", S_Music_f, "starting a background track" );
|
||||
|
@ -2200,7 +2313,7 @@ qboolean S_Init( void )
|
|||
|
||||
if( !SNDDMA_Init( host.hWnd ))
|
||||
{
|
||||
MsgDev( D_INFO, "S_Init: sound system can't be initialized\n" );
|
||||
Con_Printf( "Audio: sound system can't be initialized\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2215,6 +2328,7 @@ qboolean S_Init( void )
|
|||
SX_Init ();
|
||||
S_InitScaletable ();
|
||||
S_StopAllSounds ( true );
|
||||
S_InitSounds ();
|
||||
VOX_Init ();
|
||||
|
||||
return true;
|
||||
|
|
|
@ -71,7 +71,7 @@ float S_GetMusicVolume( void )
|
|||
S_StartBackgroundTrack
|
||||
=================
|
||||
*/
|
||||
void S_StartBackgroundTrack( const char *introTrack, const char *mainTrack, long position, qboolean fullpath )
|
||||
void S_StartBackgroundTrack( const char *introTrack, const char *mainTrack, int position, qboolean fullpath )
|
||||
{
|
||||
S_StopBackgroundTrack();
|
||||
|
||||
|
@ -84,15 +84,16 @@ void S_StartBackgroundTrack( const char *introTrack, const char *mainTrack, long
|
|||
if( mainTrack && *mainTrack == '*' )
|
||||
mainTrack = NULL;
|
||||
|
||||
if(( !introTrack || !*introTrack ) && ( !mainTrack || !*mainTrack ))
|
||||
if( !COM_CheckString( introTrack ) && !COM_CheckString( mainTrack ))
|
||||
return;
|
||||
|
||||
if( !introTrack ) introTrack = mainTrack;
|
||||
if( !*introTrack ) return;
|
||||
|
||||
if( !mainTrack || !*mainTrack ) s_bgTrack.loopName[0] = '\0';
|
||||
if( !COM_CheckString( mainTrack ))
|
||||
s_bgTrack.loopName[0] = '\0';
|
||||
else Q_strncpy( s_bgTrack.loopName, mainTrack, sizeof( s_bgTrack.loopName ));
|
||||
if( fullpath ) Msg( "MP3:Playing: %s\n", introTrack );
|
||||
|
||||
// open stream
|
||||
s_bgTrack.stream = FS_OpenStream( va( "media/%s", introTrack ));
|
||||
Q_strncpy( s_bgTrack.current, introTrack, sizeof( s_bgTrack.current ));
|
||||
|
|
|
@ -478,7 +478,7 @@ void VOX_LoadSound( channel_t *pchan, const char *pszin )
|
|||
|
||||
if( Q_strlen( psz ) > sizeof( buffer ) - 1 )
|
||||
{
|
||||
MsgDev( D_ERROR, "VOX_LoadSound: sentence is too long %s\n", psz );
|
||||
Con_Printf( S_ERROR "VOX_LoadSound: sentence is too long %s\n", psz );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -545,7 +545,7 @@ void VOX_ParseLineCommands( char *pSentenceData, int sentenceIndex )
|
|||
length = pNext - pSentenceData;
|
||||
if( tempBufferPos + length > sizeof( tempBuffer ))
|
||||
{
|
||||
MsgDev( D_ERROR, "sentence too long!\n" );
|
||||
Con_Printf( S_ERROR "sentence too long!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -606,7 +606,7 @@ void VOX_ReadSentenceFile( const char *psentenceFileName )
|
|||
{
|
||||
char c, *pch, *pFileData;
|
||||
char *pchlast, *pSentenceData;
|
||||
int fileSize;
|
||||
size_t fileSize;
|
||||
|
||||
// load file
|
||||
pFileData = (char *)FS_LoadFile( psentenceFileName, &fileSize, false );
|
||||
|
@ -617,6 +617,12 @@ void VOX_ReadSentenceFile( const char *psentenceFileName )
|
|||
|
||||
while( pch < pchlast )
|
||||
{
|
||||
if( g_numSentences >= MAX_SENTENCES )
|
||||
{
|
||||
Con_Printf( S_ERROR "VOX_Init: too many sentences specified\n" );
|
||||
break;
|
||||
}
|
||||
|
||||
// only process this pass on sentences
|
||||
pSentenceData = NULL;
|
||||
|
||||
|
|
|
@ -81,6 +81,8 @@ extern byte *sndpool;
|
|||
#define S_RAW_SOUND_SOUNDTRACK -1
|
||||
#define S_RAW_SAMPLES_PRECISION_BITS 14
|
||||
|
||||
#define CIN_FRAMETIME (1.0f / 30.0f)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int left;
|
||||
|
@ -164,6 +166,8 @@ typedef struct rawchan_s
|
|||
vec3_t origin; // only use if fixed_origin is set
|
||||
float radius; // radius of this sound effect
|
||||
volatile uint s_rawend;
|
||||
wavdata_t sound_info; // advance play position
|
||||
float oldtime; // catch time jumps
|
||||
size_t max_samples; // buffer length
|
||||
portable_samplepair_t rawsamples[1]; // variable sized
|
||||
} rawchan_t;
|
||||
|
@ -233,22 +237,6 @@ typedef struct
|
|||
int source; // may be game, menu, etc
|
||||
} bg_track_t;
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
|
||||
SYSTEM SPECIFIC FUNCTIONS
|
||||
|
||||
====================================================================
|
||||
*/
|
||||
// initializes cycling through a DMA buffer and returns information on it
|
||||
qboolean SNDDMA_Init( void *hInst );
|
||||
int SNDDMA_GetSoundtime( void );
|
||||
void SNDDMA_Shutdown( void );
|
||||
void SNDDMA_BeginPainting( void );
|
||||
void SNDDMA_Submit( void );
|
||||
void SNDDMA_LockSound( void );
|
||||
void SNDDMA_UnlockSound( void );
|
||||
|
||||
//====================================================================
|
||||
|
||||
#define MAX_DYNAMIC_CHANNELS (60 + NUM_AMBIENTS)
|
||||
|
@ -275,6 +263,7 @@ extern convar_t *s_lerping;
|
|||
extern convar_t *dsp_off;
|
||||
extern convar_t *s_test; // cvar to testify new effects
|
||||
extern convar_t *s_samplecount;
|
||||
extern convar_t *snd_mute_losefocus;
|
||||
|
||||
void S_InitScaletable( void );
|
||||
wavdata_t *S_LoadSound( sfx_t *sfx );
|
||||
|
@ -301,6 +290,7 @@ char *S_SkipSoundChar( const char *pch );
|
|||
sfx_t *S_FindName( const char *name, int *pfInCache );
|
||||
sound_t S_RegisterSound( const char *name );
|
||||
void S_FreeSound( sfx_t *sfx );
|
||||
void S_InitSounds( void );
|
||||
|
||||
// s_dsp.c
|
||||
void SX_Init( void );
|
||||
|
@ -316,6 +306,7 @@ void S_Activate( qboolean active );
|
|||
void S_SoundList_f( void );
|
||||
void S_SoundInfo_f( void );
|
||||
|
||||
struct ref_viewpass_s;
|
||||
channel_t *SND_PickDynamicChannel( int entnum, int channel, sfx_t *sfx, qboolean *ignore );
|
||||
channel_t *SND_PickStaticChannel( const vec3_t pos, sfx_t *sfx );
|
||||
int S_GetCurrentStaticSounds( soundlist_t *pout, int size );
|
||||
|
@ -324,6 +315,7 @@ sfx_t *S_GetSfxByHandle( sound_t handle );
|
|||
rawchan_t *S_FindRawChannel( int entnum, qboolean create );
|
||||
void S_RawSamples( uint samples, uint rate, word width, word channels, const byte *data, int entnum );
|
||||
void S_StopSound( int entnum, int channel, const char *soundname );
|
||||
void S_UpdateFrame( struct ref_viewpass_s *rvp );
|
||||
uint S_GetRawSamplesLength( int entnum );
|
||||
void S_ClearRawChannel( int entnum );
|
||||
void S_StopAllSounds( qboolean ambient );
|
||||
|
|
|
@ -201,7 +201,7 @@ static int ParseDirective( const char *pText )
|
|||
}
|
||||
else
|
||||
{
|
||||
MsgDev( D_ERROR, "unknown token: %s\n", pText );
|
||||
Con_DPrintf( S_ERROR "unknown token: %s\n", pText );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
|
|||
|
||||
if( IsEndOfText( trim ))
|
||||
{
|
||||
MsgDev( D_ERROR, "TextMessage: unexpected '}' found, line %d\n", lineNumber );
|
||||
Con_Reportf( "TextMessage: unexpected '}' found, line %d\n", lineNumber );
|
||||
return;
|
||||
}
|
||||
Q_strcpy( currentName, trim );
|
||||
|
@ -260,9 +260,9 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
|
|||
int length = Q_strlen( currentName );
|
||||
|
||||
// save name on name heap
|
||||
if( lastNamePos + length > 16384 )
|
||||
if( lastNamePos + length > 32768 )
|
||||
{
|
||||
MsgDev( D_ERROR, "TextMessage: error while parsing!\n" );
|
||||
Con_Reportf( "TextMessage: error while parsing!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -285,7 +285,7 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
|
|||
}
|
||||
if( IsStartOfText( trim ))
|
||||
{
|
||||
MsgDev( D_ERROR, "TextMessage: unexpected '{' found, line %d\n", lineNumber );
|
||||
Con_Reportf( "TextMessage: unexpected '{' found, line %d\n", lineNumber );
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
@ -296,12 +296,12 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
|
|||
|
||||
if( messageCount >= MAX_MESSAGES )
|
||||
{
|
||||
MsgDev( D_WARN, "Too many messages in titles.txt, max is %d\n", MAX_MESSAGES );
|
||||
Con_Printf( S_WARN "Too many messages in titles.txt, max is %d\n", MAX_MESSAGES );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MsgDev( D_NOTE, "TextMessage: parsed %d text messages\n", messageCount );
|
||||
Con_Reportf( "TextMessage: parsed %d text messages\n", messageCount );
|
||||
nameHeapSize = lastNamePos;
|
||||
textHeapSize = 0;
|
||||
|
||||
|
@ -317,7 +317,7 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
|
|||
}
|
||||
|
||||
// must malloc because we need to be able to clear it after initialization
|
||||
clgame.titles = (client_textmessage_t *)Mem_Alloc( cls.mempool, textHeapSize + nameHeapSize + messageSize );
|
||||
clgame.titles = (client_textmessage_t *)Mem_Calloc( cls.mempool, textHeapSize + nameHeapSize + messageSize );
|
||||
|
||||
// copy table over
|
||||
memcpy( clgame.titles, textMessages, messageSize );
|
||||
|
@ -325,21 +325,23 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
|
|||
// copy Name heap
|
||||
pNameHeap = ((char *)clgame.titles) + messageSize;
|
||||
memcpy( pNameHeap, nameHeap, nameHeapSize );
|
||||
nameOffset = pNameHeap - clgame.titles[0].pName;
|
||||
//nameOffset = pNameHeap - clgame.titles[0].pName; //undefined on amd64
|
||||
|
||||
|
||||
// copy text & fixup pointers
|
||||
pCurrentText = pNameHeap + nameHeapSize;
|
||||
|
||||
for( i = 0; i < messageCount; i++ )
|
||||
{
|
||||
clgame.titles[i].pName += nameOffset; // adjust name pointer (parallel buffer)
|
||||
clgame.titles[i].pName = pNameHeap; // adjust name pointer (parallel buffer)
|
||||
Q_strcpy( pCurrentText, clgame.titles[i].pMessage ); // copy text over
|
||||
clgame.titles[i].pMessage = pCurrentText;
|
||||
pNameHeap += Q_strlen( pNameHeap ) + 1;
|
||||
pCurrentText += Q_strlen( pCurrentText ) + 1;
|
||||
}
|
||||
|
||||
if(( pCurrentText - (char *)clgame.titles ) != ( textHeapSize + nameHeapSize + messageSize ))
|
||||
MsgDev( D_ERROR, "TextMessage: overflow text message buffer!\n" );
|
||||
Con_DPrintf( S_ERROR "TextMessage: overflow text message buffer!\n" );
|
||||
|
||||
clgame.numTitles = messageCount;
|
||||
}
|
|
@ -28,6 +28,7 @@ GNU General Public License for more details.
|
|||
#include <SDL_events.h>
|
||||
static SDL_Cursor* s_pDefaultCursor[20];
|
||||
#endif
|
||||
#include "platform/platform.h"
|
||||
|
||||
int g_textures[VGUI_MAX_TEXTURES];
|
||||
int g_textureId = 0;
|
||||
|
@ -81,7 +82,7 @@ void GAME_EXPORT VGUI_GetMousePos( int *_x, int *_y )
|
|||
float yscale = (float)glState.height / (float)clgame.scrInfo.iHeight;
|
||||
int x, y;
|
||||
|
||||
CL_GetMousePosition( &x, &y );
|
||||
Platform_GetMousePos( &x, &y );
|
||||
*_x = x / xscale, *_y = y / yscale;
|
||||
}
|
||||
|
||||
|
@ -246,7 +247,7 @@ void VGui_Startup( int width, int height )
|
|||
F( &vgui );
|
||||
vgui.initialized = true;
|
||||
VGUI_InitCursors();
|
||||
MsgDev( D_INFO, "vgui_support: found interal client support\n" );
|
||||
Con_Reportf( "vgui_support: found interal client support\n" );
|
||||
}
|
||||
}
|
||||
#endif // XASH_INTERNAL_GAMELIBS
|
||||
|
@ -261,7 +262,7 @@ void VGui_Startup( int width, int height )
|
|||
Q_strncpy( vguiloader, VGUI_SUPPORT_DLL, 256 );
|
||||
|
||||
if( !COM_LoadLibrary( vguilib, false, false ) )
|
||||
MsgDev( D_WARN, "VGUI preloading failed. Default library will be used! Reason: %s\n", COM_GetLibraryError());
|
||||
Con_Reportf( S_WARN "VGUI preloading failed. Default library will be used! Reason: %s\n", COM_GetLibraryError());
|
||||
}
|
||||
|
||||
if( Q_strstr( GI->client_lib, ".dll" ) )
|
||||
|
@ -280,9 +281,9 @@ void VGui_Startup( int width, int height )
|
|||
if( !s_pVGuiSupport )
|
||||
{
|
||||
if( FS_FileExists( vguiloader, false ) )
|
||||
MsgDev( D_ERROR, "Failed to load vgui_support library: %s", COM_GetLibraryError() );
|
||||
Con_Reportf( S_ERROR "Failed to load vgui_support library: %s", COM_GetLibraryError() );
|
||||
else
|
||||
MsgDev( D_INFO, "vgui_support: not found\n" );
|
||||
Con_Reportf( "vgui_support: not found\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -294,7 +295,7 @@ void VGui_Startup( int width, int height )
|
|||
VGUI_InitCursors();
|
||||
}
|
||||
else
|
||||
MsgDev( D_ERROR, "Failed to find vgui_support library entry point!\n" );
|
||||
Con_Reportf( S_ERROR "Failed to find vgui_support library entry point!\n" );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -552,7 +553,7 @@ void GAME_EXPORT VGUI_DrawShutdown( void )
|
|||
|
||||
for( i = 1; i < g_textureId; i++ )
|
||||
{
|
||||
GL_FreeImage( va( "*vgui%i", i ));
|
||||
GL_FreeTexture( g_textures[i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -584,7 +585,7 @@ void GAME_EXPORT VGUI_UploadTexture( int id, const char *buffer, int width, int
|
|||
|
||||
if( id <= 0 || id >= VGUI_MAX_TEXTURES )
|
||||
{
|
||||
MsgDev( D_ERROR, "VGUI_UploadTexture: bad texture %i. Ignored\n", id );
|
||||
Con_DPrintf( S_ERROR "VGUI_UploadTexture: bad texture %i. Ignored\n", id );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -598,8 +599,7 @@ void GAME_EXPORT VGUI_UploadTexture( int id, const char *buffer, int width, int
|
|||
r_image.flags = IMAGE_HAS_COLOR|IMAGE_HAS_ALPHA;
|
||||
r_image.buffer = (byte *)buffer;
|
||||
|
||||
g_textures[id] = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE, false );
|
||||
g_iBoundTexture = id;
|
||||
g_textures[id] = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -616,7 +616,7 @@ void GAME_EXPORT VGUI_CreateTexture( int id, int width, int height )
|
|||
|
||||
if( id <= 0 || id >= VGUI_MAX_TEXTURES )
|
||||
{
|
||||
MsgDev( D_ERROR, "VGUI_CreateTexture: bad texture %i. Ignored\n", id );
|
||||
Con_Reportf( S_ERROR "VGUI_CreateTexture: bad texture %i. Ignored\n", id );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -630,7 +630,7 @@ void GAME_EXPORT VGUI_CreateTexture( int id, int width, int height )
|
|||
r_image.flags = IMAGE_HAS_ALPHA;
|
||||
r_image.buffer = NULL;
|
||||
|
||||
g_textures[id] = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE|TF_NEAREST, false );
|
||||
g_textures[id] = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE|TF_NEAREST );
|
||||
g_iBoundTexture = id;
|
||||
}
|
||||
|
||||
|
@ -638,7 +638,7 @@ void GAME_EXPORT VGUI_UploadTextureBlock( int id, int drawX, int drawY, const by
|
|||
{
|
||||
if( id <= 0 || id >= VGUI_MAX_TEXTURES || g_textures[id] == 0 || g_textures[id] == tr.whiteTexture )
|
||||
{
|
||||
MsgDev( D_ERROR, "VGUI_UploadTextureBlock: bad texture %i. Ignored\n", id );
|
||||
Con_Reportf( S_ERROR "VGUI_UploadTextureBlock: bad texture %i. Ignored\n", id );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -698,7 +698,7 @@ returns wide and tall for currently binded texture
|
|||
*/
|
||||
void GAME_EXPORT VGUI_GetTextureSizes( int *width, int *height )
|
||||
{
|
||||
gltexture_t *glt;
|
||||
gl_texture_t *glt;
|
||||
int texnum;
|
||||
|
||||
if( g_iBoundTexture )
|
||||
|
|
118
engine/client/vgui/vgui_main.h
Normal file
118
engine/client/vgui/vgui_main.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
vgui_main.h - vgui main header
|
||||
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 VGUI_MAIN_H
|
||||
#define VGUI_MAIN_H
|
||||
|
||||
#include<VGUI.h>
|
||||
#include<VGUI_App.h>
|
||||
#include<VGUI_Font.h>
|
||||
#include<VGUI_Panel.h>
|
||||
#include<VGUI_Cursor.h>
|
||||
#include<VGUI_SurfaceBase.h>
|
||||
#include<VGUI_InputSignal.h>
|
||||
#include<VGUI_MouseCode.h>
|
||||
#include<VGUI_KeyCode.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
struct PaintStack
|
||||
{
|
||||
Panel *m_pPanel;
|
||||
int iTranslateX;
|
||||
int iTranslateY;
|
||||
int iScissorLeft;
|
||||
int iScissorRight;
|
||||
int iScissorTop;
|
||||
int iScissorBottom;
|
||||
};
|
||||
|
||||
class CEngineSurface : public SurfaceBase
|
||||
{
|
||||
private:
|
||||
void InitVertex( vpoint_t &vertex, int x, int y, float u, float v );
|
||||
public:
|
||||
CEngineSurface( Panel *embeddedPanel );
|
||||
~CEngineSurface();
|
||||
public:
|
||||
// not used in engine instance
|
||||
virtual bool setFullscreenMode( int wide, int tall, int bpp ) { return false; }
|
||||
virtual void setWindowedMode( void ) { }
|
||||
virtual void setTitle( const char *title ) { }
|
||||
virtual void createPopup( Panel* embeddedPanel ) { }
|
||||
virtual bool isWithin( int x, int y ) { return true; }
|
||||
void SetupPaintState( const PaintStack *paintState );
|
||||
#ifdef NEW_VGUI_DLL
|
||||
virtual void GetMousePos( int &x, int &y ) { }
|
||||
#endif
|
||||
virtual bool hasFocus( void ) { return true; }
|
||||
protected:
|
||||
virtual int createNewTextureID( void );
|
||||
virtual void drawSetColor( int r, int g, int b, int a );
|
||||
virtual void drawSetTextColor( int r, int g, int b, int a );
|
||||
virtual void drawFilledRect( int x0, int y0, int x1, int y1 );
|
||||
virtual void drawOutlinedRect( int x0,int y0,int x1,int y1 );
|
||||
virtual void drawSetTextFont( Font *font );
|
||||
virtual void drawSetTextPos( int x, int y );
|
||||
virtual void drawPrintText( const char* text, int textLen );
|
||||
virtual void drawSetTextureRGBA( int id, const char* rgba, int wide, int tall );
|
||||
virtual void drawSetTexture( int id );
|
||||
virtual void drawTexturedRect( int x0, int y0, int x1, int y1 );
|
||||
virtual void drawPrintChar( int x, int y, int wide, int tall, float s0, float t0, float s1, float t1, int color[4] );
|
||||
virtual void addCharToBuffer( const vpoint_t *ul, const vpoint_t *lr, int color[4] );
|
||||
virtual void setCursor( Cursor* cursor );
|
||||
virtual void pushMakeCurrent( Panel* panel, bool useInsets );
|
||||
virtual void popMakeCurrent( Panel* panel );
|
||||
// not used in engine instance
|
||||
virtual bool createPlat( void ) { return false; }
|
||||
virtual bool recreateContext( void ) { return false; }
|
||||
virtual void enableMouseCapture( bool state ) { }
|
||||
virtual void invalidate( Panel *panel ) { }
|
||||
virtual void setAsTopMost( bool state ) { }
|
||||
virtual void applyChanges( void ) { }
|
||||
virtual void swapBuffers( void ) { }
|
||||
virtual void flushBuffer( void );
|
||||
protected:
|
||||
int _drawTextPos[2];
|
||||
int _drawColor[4];
|
||||
int _drawTextColor[4];
|
||||
int _translateX, _translateY;
|
||||
int _currentTexture;
|
||||
Panel *currentPanel;
|
||||
};
|
||||
|
||||
// initialize VGUI::App as external (part of engine)
|
||||
class CEngineApp : public App
|
||||
{
|
||||
public:
|
||||
virtual void main( int argc, char* argv[] ) { }
|
||||
virtual void setCursorPos( int x, int y ); // we need to recompute abs position to window
|
||||
virtual void getCursorPos( int &x,int &y );
|
||||
protected:
|
||||
virtual void platTick(void) { }
|
||||
};
|
||||
|
||||
extern Panel *rootPanel;
|
||||
extern CEngineSurface *engSurface;
|
||||
extern CEngineApp *engApp;
|
||||
|
||||
//
|
||||
// vgui_input.cpp
|
||||
//
|
||||
void VGUI_InitCursors( void );
|
||||
void VGUI_CursorSelect( Cursor *cursor );
|
||||
void VGUI_ActivateCurrentCursor( void );
|
||||
|
||||
#endif//VGUI_MAIN_H
|
|
@ -19,6 +19,7 @@ GNU General Public License for more details.
|
|||
#include "mod_local.h"
|
||||
#include "input.h"
|
||||
#include "vid_common.h"
|
||||
#include "platform/platform.h"
|
||||
|
||||
#define WINDOW_NAME XASH_ENGINE_NAME " Window" // Half-Life
|
||||
|
||||
|
@ -26,8 +27,10 @@ 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;
|
||||
|
@ -46,6 +49,7 @@ 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;
|
||||
|
@ -124,7 +128,7 @@ void GL_CheckExtension( const char *name, const dllfunc_t *funcs, const char *cv
|
|||
convar_t *parm = NULL;
|
||||
const char *extensions_string;
|
||||
|
||||
MsgDev( D_NOTE, "GL_CheckExtension: %s ", name );
|
||||
Con_Reportf( "GL_CheckExtension: %s ", name );
|
||||
GL_SetExtension( r_ext, true );
|
||||
|
||||
if( cvarname )
|
||||
|
@ -135,7 +139,7 @@ void GL_CheckExtension( const char *name, const dllfunc_t *funcs, const char *cv
|
|||
|
||||
if(( parm && !CVAR_TO_BOOL( parm )) || ( !CVAR_TO_BOOL( gl_extensions ) && r_ext != GL_OPENGL_110 ))
|
||||
{
|
||||
MsgDev( D_NOTE, "- disabled\n" );
|
||||
Con_Reportf( "- disabled\n" );
|
||||
GL_SetExtension( r_ext, false );
|
||||
return; // nothing to process at
|
||||
}
|
||||
|
@ -145,7 +149,7 @@ void GL_CheckExtension( const char *name, const dllfunc_t *funcs, const char *cv
|
|||
if(( name[2] == '_' || name[3] == '_' ) && !Q_strstr( extensions_string, name ))
|
||||
{
|
||||
GL_SetExtension( r_ext, false ); // update render info
|
||||
MsgDev( D_NOTE, "- ^1failed\n" );
|
||||
Con_Reportf( "- ^1failed\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -161,8 +165,8 @@ void GL_CheckExtension( const char *name, const dllfunc_t *funcs, const char *cv
|
|||
}
|
||||
|
||||
if( GL_Support( r_ext ))
|
||||
MsgDev( D_NOTE, "- ^2enabled\n" );
|
||||
else MsgDev( D_NOTE, "- ^1failed\n" );
|
||||
Con_Reportf( "- ^2enabled\n" );
|
||||
else Con_Reportf( "- ^1failed\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -208,7 +212,7 @@ VID_StartupGamma
|
|||
void VID_StartupGamma( void )
|
||||
{
|
||||
BuildGammaTable( vid_gamma->value, vid_brightness->value );
|
||||
MsgDev( D_NOTE, "VID_StartupGamma: gamma %g brightness %g\n", vid_gamma->value, vid_brightness->value );
|
||||
Con_Reportf( "VID_StartupGamma: gamma %g brightness %g\n", vid_gamma->value, vid_brightness->value );
|
||||
ClearBits( vid_brightness->flags, FCVAR_CHANGED );
|
||||
ClearBits( vid_gamma->flags, FCVAR_CHANGED );
|
||||
}
|
||||
|
@ -233,12 +237,12 @@ R_SaveVideoMode
|
|||
*/
|
||||
void R_SaveVideoMode( int w, int h )
|
||||
{
|
||||
host.window_center_x = glState.width / 2;
|
||||
host.window_center_y = glState.height / 2;
|
||||
|
||||
glState.width = w;
|
||||
glState.height = h;
|
||||
|
||||
host.window_center_x = w / 2;
|
||||
host.window_center_y = h / 2;
|
||||
|
||||
Cvar_SetValue( "width", w );
|
||||
Cvar_SetValue( "height", h );
|
||||
|
||||
|
@ -255,10 +259,14 @@ VID_GetModeString
|
|||
*/
|
||||
const char *VID_GetModeString( int vid_mode )
|
||||
{
|
||||
vidmode_t *vidmode;
|
||||
if( vid_mode < 0 || vid_mode > R_MaxVideoModes() )
|
||||
return NULL;
|
||||
|
||||
return R_GetVideoMode( vid_mode ).desc;
|
||||
if( !( vidmode = R_GetVideoMode( vid_mode ) ) )
|
||||
return NULL;
|
||||
|
||||
return vidmode->desc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -324,7 +332,7 @@ static void GL_SetDefaults( void )
|
|||
pglDisable( GL_BLEND );
|
||||
pglDisable( GL_ALPHA_TEST );
|
||||
pglDisable( GL_POLYGON_OFFSET_FILL );
|
||||
pglAlphaFunc( GL_GREATER, 0.0f );
|
||||
pglAlphaFunc( GL_GREATER, DEFAULT_ALPHATEST );
|
||||
pglEnable( GL_TEXTURE_2D );
|
||||
pglShadeModel( GL_SMOOTH );
|
||||
pglFrontFace( GL_CCW );
|
||||
|
@ -389,12 +397,17 @@ static void VID_Mode_f( void )
|
|||
{
|
||||
case 2:
|
||||
{
|
||||
vidmode_t vidmode;
|
||||
vidmode_t *vidmode;
|
||||
|
||||
vidmode = R_GetVideoMode( Q_atoi( Cmd_Argv( 1 )) );
|
||||
if( !vidmode )
|
||||
{
|
||||
Con_Print( S_ERROR "unable to set mode, backend returned null" );
|
||||
return;
|
||||
}
|
||||
|
||||
w = vidmode.width;
|
||||
h = vidmode.height;
|
||||
w = vidmode->width;
|
||||
h = vidmode->height;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
|
@ -404,7 +417,7 @@ static void VID_Mode_f( void )
|
|||
break;
|
||||
}
|
||||
default:
|
||||
Msg( "Usage: vid_mode <modenum>|<width height>\n" );
|
||||
Msg( S_USAGE "vid_mode <modenum>|<width height>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -426,6 +439,7 @@ void GL_InitCommands( void )
|
|||
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" );
|
||||
|
@ -452,13 +466,15 @@ void GL_InitCommands( void )
|
|||
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_msaa = Cvar_Get( "gl_msaa", "0", FCVAR_GLCONFIG, "MSAA samples. Use with caution, engine may fail with some values" );
|
||||
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
|
||||
|
@ -551,10 +567,10 @@ qboolean R_Init( void )
|
|||
GL_SetDefaultState();
|
||||
|
||||
// create the window and set up the context
|
||||
if( !R_Init_OpenGL( ))
|
||||
if( !R_Init_Video( ))
|
||||
{
|
||||
GL_RemoveCommands();
|
||||
R_Free_OpenGL();
|
||||
R_Free_Video();
|
||||
|
||||
Sys_Error( "Can't initialize video subsystem\nProbably driver was not installed" );
|
||||
return false;
|
||||
|
@ -563,7 +579,6 @@ qboolean R_Init( void )
|
|||
host.renderinfo_changed = false;
|
||||
r_temppool = Mem_AllocPool( "Render Zone" );
|
||||
|
||||
GL_InitExtensions();
|
||||
GL_SetDefaults();
|
||||
R_InitImages();
|
||||
R_SpriteInit();
|
||||
|
@ -605,51 +620,51 @@ void R_Shutdown( void )
|
|||
Mem_FreePool( &r_temppool );
|
||||
|
||||
// shut down OS specific OpenGL stuff like contexts, etc.
|
||||
R_Free_OpenGL();
|
||||
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;
|
||||
char *str;
|
||||
|
||||
if( !gl_check_errors->value )
|
||||
if( !CVAR_TO_BOOL( gl_check_errors ))
|
||||
return;
|
||||
|
||||
if(( err = pglGetError( )) == GL_NO_ERROR )
|
||||
return;
|
||||
|
||||
switch( err )
|
||||
{
|
||||
case GL_STACK_OVERFLOW:
|
||||
str = "GL_STACK_OVERFLOW";
|
||||
break;
|
||||
case GL_STACK_UNDERFLOW:
|
||||
str = "GL_STACK_UNDERFLOW";
|
||||
break;
|
||||
case GL_INVALID_ENUM:
|
||||
str = "GL_INVALID_ENUM";
|
||||
break;
|
||||
case GL_INVALID_VALUE:
|
||||
str = "GL_INVALID_VALUE";
|
||||
break;
|
||||
case GL_INVALID_OPERATION:
|
||||
str = "GL_INVALID_OPERATION";
|
||||
break;
|
||||
case GL_OUT_OF_MEMORY:
|
||||
str = "GL_OUT_OF_MEMORY";
|
||||
break;
|
||||
default:
|
||||
str = "UNKNOWN ERROR";
|
||||
break;
|
||||
}
|
||||
|
||||
Con_Printf( S_OPENGL_ERROR "%s (called at %s:%i)\n", str, filename, fileline );
|
||||
Con_Printf( S_OPENGL_ERROR "%s (called at %s:%i)\n", GL_ErrorString( err ), filename, fileline );
|
||||
}
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
#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;
|
||||
|
@ -9,14 +12,6 @@ typedef struct vidmode_s
|
|||
int height;
|
||||
} vidmode_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
rserr_ok,
|
||||
rserr_invalid_fullscreen,
|
||||
rserr_invalid_mode,
|
||||
rserr_unknown
|
||||
} rserr_t;
|
||||
|
||||
// minimal recommended resolution
|
||||
#define VID_MIN_WIDTH 640
|
||||
#define VID_MIN_HEIGHT 480
|
||||
|
@ -27,6 +22,7 @@ typedef enum
|
|||
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 );
|
||||
|
@ -39,23 +35,4 @@ 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 );
|
||||
|
||||
//
|
||||
// platform-defined calls
|
||||
//
|
||||
void GL_InitExtensions( void );
|
||||
void VID_RestoreScreenResolution( void );
|
||||
qboolean VID_CreateWindow( int width, int height, qboolean fullscreen );
|
||||
void VID_DestroyWindow( void );
|
||||
qboolean R_Init_OpenGL( void );
|
||||
void R_Free_OpenGL( void );
|
||||
void *GL_GetProcAddress( const char *name );
|
||||
qboolean GL_CreateContext( void );
|
||||
qboolean GL_UpdateContext( void );
|
||||
qboolean GL_DeleteContext( void );
|
||||
int R_MaxVideoModes();
|
||||
vidmode_t R_GetVideoMode( int num );
|
||||
rserr_t R_ChangeDisplaySettings( int width, int height, qboolean fullscreen );
|
||||
void R_ChangeDisplaySettingsFast( int width, int height ); // for fast resizing
|
||||
qboolean VID_SetMode( void );
|
||||
|
||||
#endif // VID_COMMON
|
||||
|
|
|
@ -18,7 +18,7 @@ GNU General Public License for more details.
|
|||
|
||||
#define CVOXWORDMAX 64
|
||||
#define CVOXZEROSCANMAX 255 // scan up to this many samples for next zero crossing
|
||||
#define MAX_SENTENCES 2048
|
||||
#define MAX_SENTENCES 4096
|
||||
#define SENTENCE_INDEX -99999 // unique sentence index
|
||||
|
||||
typedef struct voxword_s
|
||||
|
|
287
engine/common/base_cmd.c
Normal file
287
engine/common/base_cmd.c
Normal file
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
base_cmd.c - command & cvar hashmap. Insipred by Doom III
|
||||
Copyright (C) 2016 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 "base_cmd.h"
|
||||
#include "cdll_int.h"
|
||||
|
||||
// TODO: use another hash function, as COM_HashKey depends on string length
|
||||
#define HASH_SIZE 128 // 128 * 4 * 4 == 2048 bytes
|
||||
static base_command_hashmap_t *hashed_cmds[HASH_SIZE];
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_FindInBucket
|
||||
|
||||
Find base command in bucket
|
||||
============
|
||||
*/
|
||||
base_command_hashmap_t *BaseCmd_FindInBucket( base_command_hashmap_t *bucket, base_command_type_e type, const char *name )
|
||||
{
|
||||
base_command_hashmap_t *i = bucket;
|
||||
for( ; i && ( i->type != type || Q_stricmp( name, i->name ) ); // filter out
|
||||
i = i->next );
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_GetBucket
|
||||
|
||||
Get bucket which contain basecmd by given name
|
||||
============
|
||||
*/
|
||||
base_command_hashmap_t *BaseCmd_GetBucket( const char *name )
|
||||
{
|
||||
return hashed_cmds[ COM_HashKey( name, HASH_SIZE ) ];
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Find
|
||||
|
||||
Find base command in hashmap
|
||||
============
|
||||
*/
|
||||
base_command_t *BaseCmd_Find( base_command_type_e type, const char *name )
|
||||
{
|
||||
base_command_hashmap_t *base = BaseCmd_GetBucket( name );
|
||||
base_command_hashmap_t *found = BaseCmd_FindInBucket( base, type, name );
|
||||
|
||||
if( found )
|
||||
return found->basecmd;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Find
|
||||
|
||||
Find every type of base command and write into arguments
|
||||
============
|
||||
*/
|
||||
void BaseCmd_FindAll(const char *name, base_command_t **cmd, base_command_t **alias, base_command_t **cvar)
|
||||
{
|
||||
base_command_hashmap_t *base = BaseCmd_GetBucket( name );
|
||||
base_command_hashmap_t *i = base;
|
||||
|
||||
ASSERT( cmd && alias && cvar );
|
||||
|
||||
*cmd = *alias = *cvar = NULL;
|
||||
|
||||
for( ; i; i = i->next )
|
||||
{
|
||||
if( !Q_stricmp( i->name, name ) )
|
||||
{
|
||||
switch( i->type )
|
||||
{
|
||||
case HM_CMD:
|
||||
*cmd = i->basecmd;
|
||||
break;
|
||||
case HM_CMDALIAS:
|
||||
*alias = i->basecmd;
|
||||
break;
|
||||
case HM_CVAR:
|
||||
*cvar = i->basecmd;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Insert
|
||||
|
||||
Add new typed base command to hashmap
|
||||
============
|
||||
*/
|
||||
void BaseCmd_Insert( base_command_type_e type, base_command_t *basecmd, const char *name )
|
||||
{
|
||||
uint hash = COM_HashKey( name, HASH_SIZE );
|
||||
base_command_hashmap_t *elem;
|
||||
|
||||
elem = Z_Malloc( sizeof( base_command_hashmap_t ) );
|
||||
elem->basecmd = basecmd;
|
||||
elem->type = type;
|
||||
elem->name = name;
|
||||
elem->next = hashed_cmds[hash];
|
||||
hashed_cmds[hash] = elem;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Replace
|
||||
|
||||
Used in case, when basecmd has been registered, but gamedll wants to register it's own
|
||||
============
|
||||
*/
|
||||
qboolean BaseCmd_Replace( base_command_type_e type, base_command_t *basecmd, const char *name )
|
||||
{
|
||||
base_command_hashmap_t *i = BaseCmd_GetBucket( name );
|
||||
|
||||
for( ; i && ( i->type != type || Q_stricmp( name, i->name ) ) ; // filter out
|
||||
i = i->next );
|
||||
|
||||
if( !i )
|
||||
{
|
||||
Con_Reportf( S_ERROR "BaseCmd_Replace: couldn't find %s\n", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
i->basecmd = basecmd;
|
||||
i->name = name; // may be freed after
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Remove
|
||||
|
||||
Remove base command from hashmap
|
||||
============
|
||||
*/
|
||||
void BaseCmd_Remove( base_command_type_e type, const char *name )
|
||||
{
|
||||
uint hash = COM_HashKey( name, HASH_SIZE );
|
||||
base_command_hashmap_t *i, *prev;
|
||||
|
||||
for( prev = NULL, i = hashed_cmds[hash]; i &&
|
||||
( Q_strcmp( i->name, name ) || i->type != type); // filter out
|
||||
prev = i, i = i->next );
|
||||
|
||||
if( !i )
|
||||
{
|
||||
Con_Reportf( S_ERROR "Couldn't find %s in buckets\n", name );
|
||||
return;
|
||||
}
|
||||
|
||||
if( prev )
|
||||
prev->next = i->next;
|
||||
else
|
||||
hashed_cmds[hash] = i->next;
|
||||
|
||||
Z_Free( i );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Init
|
||||
|
||||
initialize base command hashmap system
|
||||
============
|
||||
*/
|
||||
void BaseCmd_Init( void )
|
||||
{
|
||||
memset( hashed_cmds, 0, sizeof( hashed_cmds ) );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Stats_f
|
||||
|
||||
============
|
||||
*/
|
||||
void BaseCmd_Stats_f( void )
|
||||
{
|
||||
int i, minsize = 99999, maxsize = -1, empty = 0;
|
||||
|
||||
for( i = 0; i < HASH_SIZE; i++ )
|
||||
{
|
||||
base_command_hashmap_t *hm;
|
||||
int len = 0;
|
||||
|
||||
// count bucket length
|
||||
for( hm = hashed_cmds[i]; hm; hm = hm->next, len++ );
|
||||
|
||||
if( len == 0 )
|
||||
{
|
||||
empty++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( len < minsize )
|
||||
minsize = len;
|
||||
|
||||
if( len > maxsize )
|
||||
maxsize = len;
|
||||
}
|
||||
|
||||
Con_Printf( "Base command stats:\n");
|
||||
Con_Printf( "Bucket minimal length: %d\n", minsize );
|
||||
Con_Printf( "Bucket maximum length: %d\n", maxsize );
|
||||
Con_Printf( "Empty buckets: %d\n", empty );
|
||||
}
|
||||
|
||||
static void BaseCmd_CheckCvars( const char *key, const char *value, void *buffer, void *ptr )
|
||||
{
|
||||
base_command_t *v = BaseCmd_Find( HM_CVAR, key );
|
||||
qboolean *invalid = ptr;
|
||||
|
||||
if( !v )
|
||||
{
|
||||
Con_Printf( "Cvar %s is missing in basecmd\n", key );
|
||||
*invalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Stats_f
|
||||
|
||||
testing order matches cbuf execute
|
||||
============
|
||||
*/
|
||||
void BaseCmd_Test_f( void )
|
||||
{
|
||||
void *cmd;
|
||||
cmdalias_t *a;
|
||||
qboolean invalid = false;
|
||||
|
||||
// Cmd_LookupCmds don't allows to check alias, so just iterate
|
||||
for( a = Cmd_AliasGetList(); a; a = a->next )
|
||||
{
|
||||
base_command_t *v = BaseCmd_Find( HM_CMDALIAS, a->name );
|
||||
|
||||
if( !v )
|
||||
{
|
||||
Con_Printf( "Alias %s is missing in basecmd\n", a->name );
|
||||
invalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
for( cmd = Cmd_GetFirstFunctionHandle(); cmd;
|
||||
cmd = Cmd_GetNextFunctionHandle( cmd ) )
|
||||
{
|
||||
base_command_t *v = BaseCmd_Find( HM_CMD, Cmd_GetName( cmd ) );
|
||||
|
||||
if( !v )
|
||||
{
|
||||
Con_Printf( "Command %s is missing in basecmd\n", Cmd_GetName( cmd ) );
|
||||
invalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
Cvar_LookupVars( 0, NULL, &invalid, BaseCmd_CheckCvars );
|
||||
|
||||
if( !invalid )
|
||||
{
|
||||
Con_Printf( "BaseCmd is valid\n" );
|
||||
}
|
||||
}
|
59
engine/common/base_cmd.h
Normal file
59
engine/common/base_cmd.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
base_cmd.h - command & cvar hashmap. Insipred by Doom III
|
||||
Copyright (C) 2016 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 BASE_CMD_H
|
||||
#define BASE_CMD_H
|
||||
|
||||
// TODO: Find cases when command hashmap works incorrect
|
||||
// and maybe disable it
|
||||
#define XASH_HASHED_VARS
|
||||
|
||||
#ifdef XASH_HASHED_VARS
|
||||
|
||||
typedef enum base_command_type
|
||||
{
|
||||
HM_DONTCARE = 0,
|
||||
HM_CVAR,
|
||||
HM_CMD,
|
||||
HM_CMDALIAS
|
||||
} base_command_type_e;
|
||||
|
||||
typedef void base_command_t;
|
||||
|
||||
typedef struct base_command_hashmap_s
|
||||
{
|
||||
base_command_t *basecmd; // base command: cvar, alias or command
|
||||
const char *name; // key for searching
|
||||
base_command_type_e type; // type for faster searching
|
||||
struct base_command_hashmap_s *next;
|
||||
} base_command_hashmap_t;
|
||||
|
||||
|
||||
void BaseCmd_Init( void );
|
||||
base_command_hashmap_t *BaseCmd_GetBucket( const char *name );
|
||||
base_command_hashmap_t *BaseCmd_FindInBucket( base_command_hashmap_t *bucket, base_command_type_e type, const char *name );
|
||||
base_command_t *BaseCmd_Find( base_command_type_e type, const char *name );
|
||||
void BaseCmd_FindAll( const char *name,
|
||||
base_command_t **cmd, base_command_t **alias, base_command_t **cvar );
|
||||
void BaseCmd_Insert ( base_command_type_e type, base_command_t *basecmd, const char *name );
|
||||
qboolean BaseCmd_Replace( base_command_type_e type, base_command_t *basecmd, const char *name ); // only if same name
|
||||
void BaseCmd_Remove ( base_command_type_e type, const char *name );
|
||||
void BaseCmd_Stats_f( void ); // to be registered later
|
||||
void BaseCmd_Test_f( void ); // to be registered later
|
||||
|
||||
#endif // XASH_HASHED_VARS
|
||||
|
||||
#endif // BASE_CMD_H
|
|
@ -48,7 +48,7 @@ int Q_buildnum( void )
|
|||
|
||||
return b;
|
||||
#else
|
||||
return 3847;
|
||||
return 4260;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -133,9 +133,8 @@ const char *Q_buildcommit( void )
|
|||
{
|
||||
#ifdef XASH_BUILD_COMMIT
|
||||
return XASH_BUILD_COMMIT;
|
||||
#elif defined(XASH_RELEASE) // don't check it elsewhere to avoid random bugs
|
||||
return "release";
|
||||
#else
|
||||
return "notset";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ qboolean CSCR_ExpectString( parserstate_t *ps, const char *pExpect, qboolean ski
|
|||
}
|
||||
|
||||
if( skip ) ps->buf = tmp;
|
||||
if( error ) MsgDev( D_ERROR, "Syntax error in %s: got \"%s\" instead of \"%s\"\n", ps->filename, ps->token, pExpect );
|
||||
if( error ) Con_DPrintf( S_ERROR "Syntax error in %s: got \"%s\" instead of \"%s\"\n", ps->filename, ps->token, pExpect );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ cvartype_t CSCR_ParseType( parserstate_t *ps )
|
|||
return i;
|
||||
}
|
||||
|
||||
MsgDev( D_ERROR, "Cannot parse %s: Bad type %s\n", ps->filename, ps->token );
|
||||
Con_DPrintf( S_ERROR "Cannot parse %s: Bad type %s\n", ps->filename, ps->token );
|
||||
return T_NONE;
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ qboolean CSCR_ParseHeader( parserstate_t *ps )
|
|||
|
||||
if( Q_atof( ps->token ) != 1 )
|
||||
{
|
||||
MsgDev( D_ERROR, "File %s has wrong version %s!\n", ps->filename, ps->token );
|
||||
Con_DPrintf( S_ERROR "File %s has wrong version %s!\n", ps->filename, ps->token );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ qboolean CSCR_ParseHeader( parserstate_t *ps )
|
|||
|
||||
if( Q_stricmp( ps->token, "INFO_OPTIONS") && Q_stricmp( ps->token, "SERVER_OPTIONS" ))
|
||||
{
|
||||
MsgDev( D_ERROR, "DESCRIPTION must be INFO_OPTIONS or SERVER_OPTIONS\n");
|
||||
Con_DPrintf( S_ERROR "DESCRIPTION must be INFO_OPTIONS or SERVER_OPTIONS\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -223,13 +223,10 @@ int CSCR_WriteGameCVars( file_t *cfg, const char *scriptfilename )
|
|||
if( !state.buf || !length )
|
||||
return 0;
|
||||
|
||||
MsgDev( D_INFO, "Reading config script file %s\n", scriptfilename );
|
||||
Con_DPrintf( "Reading config script file %s\n", scriptfilename );
|
||||
|
||||
if( !CSCR_ParseHeader( &state ))
|
||||
{
|
||||
MsgDev( D_ERROR, "Failed to parse header!\n" );
|
||||
goto finish;
|
||||
}
|
||||
|
||||
while( !CSCR_ExpectString( &state, "}", false, false ))
|
||||
{
|
||||
|
@ -258,7 +255,7 @@ int CSCR_WriteGameCVars( file_t *cfg, const char *scriptfilename )
|
|||
}
|
||||
|
||||
if( COM_ParseFile( state.buf, state.token ))
|
||||
MsgDev( D_ERROR, "Got extra tokens!\n" );
|
||||
Con_DPrintf( S_ERROR "Got extra tokens!\n" );
|
||||
else success = true;
|
||||
finish:
|
||||
if( !success )
|
||||
|
@ -266,8 +263,8 @@ finish:
|
|||
state.token[sizeof( state.token ) - 1] = 0;
|
||||
|
||||
if( start && state.buf )
|
||||
MsgDev( D_ERROR, "Parse error in %s, byte %d, token %s\n", scriptfilename, (int)( state.buf - start ), state.token );
|
||||
else MsgDev( D_ERROR, "Parse error in %s, token %s\n", scriptfilename, state.token );
|
||||
Con_DPrintf( S_ERROR "Parse error in %s, byte %d, token %s\n", scriptfilename, (int)( state.buf - start ), state.token );
|
||||
else Con_DPrintf( S_ERROR "Parse error in %s, token %s\n", scriptfilename, state.token );
|
||||
}
|
||||
|
||||
if( start ) Mem_Free( start );
|
||||
|
@ -296,13 +293,10 @@ int CSCR_LoadDefaultCVars( const char *scriptfilename )
|
|||
if( !state.buf || !length )
|
||||
return 0;
|
||||
|
||||
MsgDev( D_INFO, "Reading config script file %s\n", scriptfilename );
|
||||
Con_DPrintf( "Reading config script file %s\n", scriptfilename );
|
||||
|
||||
if( !CSCR_ParseHeader( &state ))
|
||||
{
|
||||
MsgDev( D_ERROR, "Failed to parse header!\n" );
|
||||
goto finish;
|
||||
}
|
||||
|
||||
while( !CSCR_ExpectString( &state, "}", false, false ))
|
||||
{
|
||||
|
@ -322,15 +316,15 @@ int CSCR_LoadDefaultCVars( const char *scriptfilename )
|
|||
}
|
||||
|
||||
if( COM_ParseFile( state.buf, state.token ))
|
||||
MsgDev( D_ERROR, "Got extra tokens!\n" );
|
||||
Con_DPrintf( S_ERROR "Got extra tokens!\n" );
|
||||
else success = true;
|
||||
finish:
|
||||
if( !success )
|
||||
{
|
||||
state.token[sizeof( state.token ) - 1] = 0;
|
||||
if( start && state.buf )
|
||||
MsgDev( D_ERROR, "Parse error in %s, byte %d, token %s\n", scriptfilename, (int)( state.buf - start ), state.token );
|
||||
else MsgDev( D_ERROR, "Parse error in %s, token %s\n", scriptfilename, state.token );
|
||||
Con_DPrintf( S_ERROR "Parse error in %s, byte %d, token %s\n", scriptfilename, (int)( state.buf - start ), state.token );
|
||||
else Con_DPrintf( S_ERROR "Parse error in %s, token %s\n", scriptfilename, state.token );
|
||||
}
|
||||
|
||||
if( start ) Mem_Free( start );
|
||||
|
|
|
@ -16,6 +16,7 @@ GNU General Public License for more details.
|
|||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "server.h"
|
||||
#include "base_cmd.h"
|
||||
|
||||
#define MAX_CMD_BUFFER 32768
|
||||
#define MAX_CMD_LINE 2048
|
||||
|
@ -100,7 +101,7 @@ void Cbuf_AddText( const char *text )
|
|||
|
||||
if(( cmd_text.cursize + l ) >= cmd_text.maxsize )
|
||||
{
|
||||
MsgDev( D_WARN, "Cbuf_AddText: overflow\n" );
|
||||
Con_Reportf( S_WARN "Cbuf_AddText: overflow\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -122,7 +123,7 @@ void Cbuf_InsertText( const char *text )
|
|||
|
||||
if(( cmd_text.cursize + l ) >= cmd_text.maxsize )
|
||||
{
|
||||
MsgDev( D_WARN, "Cbuf_InsertText: overflow\n" );
|
||||
Con_Reportf( S_WARN "Cbuf_InsertText: overflow\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -178,7 +179,7 @@ void Cbuf_Execute( void )
|
|||
|
||||
if( i >= ( MAX_CMD_LINE - 1 ))
|
||||
{
|
||||
MsgDev( D_ERROR, "Cbuf_Execute: command string owerflow\n" );
|
||||
Con_DPrintf( S_ERROR "Cbuf_Execute: command string owerflow\n" );
|
||||
line[0] = 0;
|
||||
}
|
||||
else
|
||||
|
@ -380,6 +381,10 @@ void Cmd_Alias_f( void )
|
|||
if( prev ) prev->next = a;
|
||||
else cmd_alias = a;
|
||||
a->next = cur;
|
||||
|
||||
#if defined( XASH_HASHED_VARS )
|
||||
BaseCmd_Insert( HM_CMDALIAS, a, a->name );
|
||||
#endif
|
||||
}
|
||||
|
||||
// copy the rest of the command line
|
||||
|
@ -425,6 +430,9 @@ static void Cmd_UnAlias_f ( void )
|
|||
{
|
||||
if( !Q_strcmp( s, a->name ))
|
||||
{
|
||||
#if defined( XASH_HASHED_VARS )
|
||||
BaseCmd_Remove( HM_CMDALIAS, a->name );
|
||||
#endif
|
||||
if( a == cmd_alias )
|
||||
cmd_alias = a->next;
|
||||
if( p ) p->next = a->next;
|
||||
|
@ -603,32 +611,40 @@ void Cmd_TokenizeString( char *text )
|
|||
|
||||
/*
|
||||
============
|
||||
Cmd_AddCommand
|
||||
Cmd_AddCommandEx
|
||||
============
|
||||
*/
|
||||
void Cmd_AddCommand( const char *cmd_name, xcommand_t function, const char *cmd_desc )
|
||||
static int Cmd_AddCommandEx( const char *funcname, const char *cmd_name, xcommand_t function,
|
||||
const char *cmd_desc, int iFlags )
|
||||
{
|
||||
cmd_t *cmd, *cur, *prev;
|
||||
|
||||
if( !COM_CheckString( cmd_name ))
|
||||
{
|
||||
Con_Reportf( S_ERROR "Cmd_AddCommand: NULL name\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// fail if the command is a variable name
|
||||
if( Cvar_FindVar( cmd_name ))
|
||||
{
|
||||
Con_Printf( S_ERROR "Cmd_AddCommand: %s already defined as a var\n", cmd_name );
|
||||
return;
|
||||
Con_DPrintf( S_ERROR "Cmd_AddServerCommand: %s already defined as a var\n", cmd_name );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// fail if the command already exists
|
||||
if( Cmd_Exists( cmd_name ))
|
||||
{
|
||||
Con_Printf( S_ERROR "Cmd_AddCommand: %s already defined\n", cmd_name );
|
||||
return;
|
||||
Con_DPrintf( S_ERROR "Cmd_AddServerCommand: %s already defined\n", cmd_name );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// use a small malloc to avoid zone fragmentation
|
||||
cmd = Z_Malloc( sizeof( cmd_t ));
|
||||
cmd = Z_Malloc( sizeof( cmd_t ) );
|
||||
cmd->name = copystring( cmd_name );
|
||||
cmd->desc = copystring( cmd_desc );
|
||||
cmd->function = function;
|
||||
cmd->flags = iFlags;
|
||||
|
||||
// insert it at the right alphanumeric position
|
||||
for( prev = NULL, cur = cmd_functions; cur && Q_strcmp( cur->name, cmd_name ) < 0; prev = cur, cur = cur->next );
|
||||
|
@ -636,6 +652,33 @@ void Cmd_AddCommand( const char *cmd_name, xcommand_t function, const char *cmd_
|
|||
if( prev ) prev->next = cmd;
|
||||
else cmd_functions = cmd;
|
||||
cmd->next = cur;
|
||||
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
BaseCmd_Insert( HM_CMD, cmd, cmd->name );
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_AddCommand
|
||||
============
|
||||
*/
|
||||
void Cmd_AddCommand( const char *cmd_name, xcommand_t function, const char *cmd_desc )
|
||||
{
|
||||
Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, cmd_desc, 0 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_AddRestrictedCommand
|
||||
============
|
||||
*/
|
||||
void Cmd_AddRestrictedCommand( const char *cmd_name, xcommand_t function, const char *cmd_desc )
|
||||
{
|
||||
Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, cmd_desc, CMD_LOCALONLY );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -645,41 +688,7 @@ Cmd_AddServerCommand
|
|||
*/
|
||||
void Cmd_AddServerCommand( const char *cmd_name, xcommand_t function )
|
||||
{
|
||||
cmd_t *cmd, *cur, *prev;
|
||||
|
||||
if( !cmd_name || !*cmd_name )
|
||||
{
|
||||
MsgDev( D_ERROR, "Cmd_AddServerCommand: NULL name\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// fail if the command is a variable name
|
||||
if( Cvar_FindVar( cmd_name ))
|
||||
{
|
||||
MsgDev( D_ERROR, "Cmd_AddServerCommand: %s already defined as a var\n", cmd_name );
|
||||
return;
|
||||
}
|
||||
|
||||
// fail if the command already exists
|
||||
if( Cmd_Exists( cmd_name ))
|
||||
{
|
||||
MsgDev( D_ERROR, "Cmd_AddServerCommand: %s already defined\n", cmd_name );
|
||||
return;
|
||||
}
|
||||
|
||||
// use a small malloc to avoid zone fragmentation
|
||||
cmd = Z_Malloc( sizeof( cmd_t ));
|
||||
cmd->name = copystring( cmd_name );
|
||||
cmd->desc = copystring( "server command" );
|
||||
cmd->function = function;
|
||||
cmd->flags = CMD_SERVERDLL;
|
||||
|
||||
// insert it at the right alphanumeric position
|
||||
for( prev = NULL, cur = cmd_functions; cur && Q_strcmp( cur->name, cmd_name ) < 0; prev = cur, cur = cur->next );
|
||||
|
||||
if( prev ) prev->next = cmd;
|
||||
else cmd_functions = cmd;
|
||||
cmd->next = cur;
|
||||
Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, "server command", CMD_SERVERDLL );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -689,43 +698,7 @@ Cmd_AddClientCommand
|
|||
*/
|
||||
int Cmd_AddClientCommand( const char *cmd_name, xcommand_t function )
|
||||
{
|
||||
cmd_t *cmd, *cur, *prev;
|
||||
|
||||
if( !cmd_name || !*cmd_name )
|
||||
{
|
||||
MsgDev( D_ERROR, "Cmd_AddClientCommand: NULL name\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// fail if the command is a variable name
|
||||
if( Cvar_FindVar( cmd_name ))
|
||||
{
|
||||
MsgDev( D_ERROR, "Cmd_AddClientCommand: %s already defined as a var\n", cmd_name );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// fail if the command already exists
|
||||
if( Cmd_Exists( cmd_name ))
|
||||
{
|
||||
MsgDev( D_ERROR, "Cmd_AddClientCommand: %s already defined\n", cmd_name );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// use a small malloc to avoid zone fragmentation
|
||||
cmd = Z_Malloc( sizeof( cmd_t ));
|
||||
cmd->name = copystring( cmd_name );
|
||||
cmd->desc = copystring( "client command" );
|
||||
cmd->function = function;
|
||||
cmd->flags = CMD_CLIENTDLL;
|
||||
|
||||
// insert it at the right alphanumeric position
|
||||
for( prev = NULL, cur = cmd_functions; cur && Q_strcmp( cur->name, cmd_name ) < 0; prev = cur, cur = cur->next );
|
||||
|
||||
if( prev ) prev->next = cmd;
|
||||
else cmd_functions = cmd;
|
||||
cmd->next = cur;
|
||||
|
||||
return 1;
|
||||
return Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, "client command", CMD_CLIENTDLL );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -735,43 +708,7 @@ Cmd_AddGameUICommand
|
|||
*/
|
||||
int Cmd_AddGameUICommand( const char *cmd_name, xcommand_t function )
|
||||
{
|
||||
cmd_t *cmd, *cur, *prev;
|
||||
|
||||
if( !cmd_name || !*cmd_name )
|
||||
{
|
||||
MsgDev( D_ERROR, "Cmd_AddGameUICommand: NULL name\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// fail if the command is a variable name
|
||||
if( Cvar_FindVar( cmd_name ))
|
||||
{
|
||||
MsgDev( D_ERROR, "Cmd_AddGameUICommand: %s already defined as a var\n", cmd_name );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// fail if the command already exists
|
||||
if( Cmd_Exists( cmd_name ))
|
||||
{
|
||||
MsgDev( D_ERROR, "Cmd_AddGameUICommand: %s already defined\n", cmd_name );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// use a small malloc to avoid zone fragmentation
|
||||
cmd = Z_Malloc( sizeof( cmd_t ));
|
||||
cmd->name = copystring( cmd_name );
|
||||
cmd->desc = copystring( "GameUI command" );
|
||||
cmd->function = function;
|
||||
cmd->flags = CMD_GAMEUIDLL;
|
||||
|
||||
// insert it at the right alphanumeric position
|
||||
for( prev = NULL, cur = cmd_functions; cur && Q_strcmp( cur->name, cmd_name ) < 0; prev = cur, cur = cur->next );
|
||||
|
||||
if( prev ) prev->next = cmd;
|
||||
else cmd_functions = cmd;
|
||||
cmd->next = cur;
|
||||
|
||||
return 1;
|
||||
return Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, "gameui command", CMD_GAMEUIDLL );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -794,6 +731,10 @@ void Cmd_RemoveCommand( const char *cmd_name )
|
|||
|
||||
if( !Q_strcmp( cmd_name, cmd->name ))
|
||||
{
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
BaseCmd_Remove( HM_CMD, cmd->name );
|
||||
#endif
|
||||
|
||||
*back = cmd->next;
|
||||
|
||||
if( cmd->name )
|
||||
|
@ -840,6 +781,9 @@ Cmd_Exists
|
|||
*/
|
||||
qboolean Cmd_Exists( const char *cmd_name )
|
||||
{
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
return BaseCmd_Find( HM_CMD, cmd_name ) != NULL;
|
||||
#else
|
||||
cmd_t *cmd;
|
||||
|
||||
for( cmd = cmd_functions; cmd; cmd = cmd->next )
|
||||
|
@ -848,6 +792,7 @@ qboolean Cmd_Exists( const char *cmd_name )
|
|||
return true;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -932,8 +877,9 @@ A complete command line has been parsed, so try to execute it
|
|||
*/
|
||||
void Cmd_ExecuteString( char *text )
|
||||
{
|
||||
cmd_t *cmd;
|
||||
cmdalias_t *a;
|
||||
cmd_t *cmd = NULL;
|
||||
cmdalias_t *a = NULL;
|
||||
convar_t *cvar = NULL;
|
||||
char command[MAX_CMD_LINE];
|
||||
char *pcmd = command;
|
||||
int len = 0;
|
||||
|
@ -988,9 +934,22 @@ void Cmd_ExecuteString( char *text )
|
|||
|
||||
if( !Cmd_Argc( )) return; // no tokens
|
||||
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
BaseCmd_FindAll( cmd_argv[0],
|
||||
(base_command_t**)&cmd,
|
||||
(base_command_t**)&a,
|
||||
(base_command_t**)&cvar );
|
||||
#endif
|
||||
|
||||
if( !host.apply_game_config )
|
||||
{
|
||||
// check aliases
|
||||
if( a ) // already found in basecmd
|
||||
{
|
||||
Cbuf_InsertText( a->value );
|
||||
return;
|
||||
}
|
||||
|
||||
for( a = cmd_alias; a; a = a->next )
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], a->name ))
|
||||
|
@ -1005,6 +964,12 @@ void Cmd_ExecuteString( char *text )
|
|||
if( !host.apply_game_config || !Q_strcmp( cmd_argv[0], "exec" ))
|
||||
{
|
||||
// check functions
|
||||
if( cmd && cmd->function ) // already found in basecmd
|
||||
{
|
||||
cmd->function();
|
||||
return;
|
||||
}
|
||||
|
||||
for( cmd = cmd_functions; cmd; cmd = cmd->next )
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], cmd->name ) && cmd->function )
|
||||
|
@ -1016,25 +981,27 @@ void Cmd_ExecuteString( char *text )
|
|||
}
|
||||
|
||||
// check cvars
|
||||
if( Cvar_Command( )) return;
|
||||
if( Cvar_Command( cvar )) return;
|
||||
|
||||
if( host.apply_game_config )
|
||||
return; // don't send nothing to server: we is a server!
|
||||
|
||||
#ifndef XASH_DEDICATED
|
||||
// forward the command line to the server, so the entity DLL can parse it
|
||||
if( host.type == HOST_NORMAL )
|
||||
{
|
||||
#ifndef XASH_DEDICATED
|
||||
if( cls.state >= ca_connected )
|
||||
{
|
||||
Cmd_ForwardToServer();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if( text[0] != '@' && host.type == HOST_NORMAL )
|
||||
#endif // XASH_DEDICATED
|
||||
if( text[0] != '@' && Cvar_VariableInteger( "host_gameloaded" ))
|
||||
{
|
||||
// commands with leading '@' are hidden system commands
|
||||
Con_Printf( S_WARN "Unknown command \"%s\"\n", text );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1147,6 +1114,10 @@ void Cmd_Unlink( int group )
|
|||
continue;
|
||||
}
|
||||
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
BaseCmd_Remove( HM_CMD, cmd->name );
|
||||
#endif
|
||||
|
||||
*prev = cmd->next;
|
||||
|
||||
if( cmd->name ) Mem_Free( cmd->name );
|
||||
|
@ -1197,4 +1168,9 @@ void Cmd_Init( void )
|
|||
Cmd_AddCommand( "unalias", Cmd_UnAlias_f, "remove a script function" );
|
||||
Cmd_AddCommand( "if", Cmd_If_f, "compare and set condition bits" );
|
||||
Cmd_AddCommand( "else", Cmd_Else_f, "invert condition bit" );
|
||||
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
Cmd_AddCommand( "basecmd_stats", BaseCmd_Stats_f, "print info about basecmd usage" );
|
||||
Cmd_AddCommand( "basecmd_test", BaseCmd_Test_f, "test basecmd" );
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -41,6 +41,10 @@ GNU General Public License for more details.
|
|||
// debug beams
|
||||
#define DEFAULT_LASERBEAM_PATH "sprites/laserbeam.spr"
|
||||
|
||||
#define DEFAULT_INTERNAL_PALETTE "gfx/palette.lmp"
|
||||
|
||||
#define DEFAULT_EXTERNAL_PALETTE "gfx/palette.pal"
|
||||
|
||||
// path to folders where placed all sounds
|
||||
#define DEFAULT_SOUNDPATH "sound/"
|
||||
|
||||
|
|
|
@ -40,12 +40,12 @@ void DBG_AssertFunction( qboolean fExpr, const char* szExpr, const char* szFile,
|
|||
if( fExpr ) return;
|
||||
|
||||
if( szMessage != NULL )
|
||||
MsgDev( at_error, "ASSERT FAILED:\n %s \n(%s@%d)\n%s\n", szExpr, szFile, szLine, szMessage );
|
||||
else MsgDev( at_error, "ASSERT FAILED:\n %s \n(%s@%d)\n", szExpr, szFile, szLine );
|
||||
Con_DPrintf( S_ERROR "ASSERT FAILED:\n %s \n(%s@%d)\n%s\n", szExpr, szFile, szLine, szMessage );
|
||||
else Con_DPrintf( S_ERROR "ASSERT FAILED:\n %s \n(%s@%d)\n", szExpr, szFile, szLine );
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
static long idum = 0;
|
||||
static int idum = 0;
|
||||
|
||||
#define MAX_RANDOM_RANGE 0x7FFFFFFFUL
|
||||
#define IA 16807
|
||||
|
@ -58,12 +58,12 @@ static long idum = 0;
|
|||
#define AM (1.0 / IM)
|
||||
#define RNMX (1.0 - EPS)
|
||||
|
||||
static long lran1( void )
|
||||
static int lran1( void )
|
||||
{
|
||||
static long iy = 0;
|
||||
static long iv[NTAB];
|
||||
static int iy = 0;
|
||||
static int iv[NTAB];
|
||||
int j;
|
||||
long k;
|
||||
int k;
|
||||
|
||||
if( idum <= 0 || !iy )
|
||||
{
|
||||
|
@ -100,7 +100,7 @@ static float fran1( void )
|
|||
return temp;
|
||||
}
|
||||
|
||||
void COM_SetRandomSeed( long lSeed )
|
||||
void COM_SetRandomSeed( int lSeed )
|
||||
{
|
||||
if( lSeed ) idum = lSeed;
|
||||
else idum = -time( NULL );
|
||||
|
@ -769,7 +769,7 @@ COM_CheckString
|
|||
*/
|
||||
int COM_CheckString( const char *string )
|
||||
{
|
||||
if( !string || (byte)*string <= ' ' )
|
||||
if( !string || !*string )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
@ -1009,7 +1009,7 @@ byte* COM_LoadFileForMe( const char *filename, int *pLength )
|
|||
{
|
||||
string name;
|
||||
byte *file, *pfile;
|
||||
long iLength;
|
||||
size_t iLength;
|
||||
|
||||
if( !COM_CheckString( filename ))
|
||||
{
|
||||
|
@ -1052,11 +1052,11 @@ byte *COM_LoadFile( const char *filename, int usehunk, int *pLength )
|
|||
|
||||
/*
|
||||
=============
|
||||
COM_LoadFile
|
||||
COM_SaveFile
|
||||
|
||||
=============
|
||||
*/
|
||||
int COM_SaveFile( const char *filename, const void *data, long len )
|
||||
int COM_SaveFile( const char *filename, const void *data, int len )
|
||||
{
|
||||
// check for empty filename
|
||||
if( !COM_CheckString( filename ))
|
||||
|
@ -1222,8 +1222,8 @@ int COM_CompareFileTime( const char *filename1, const char *filename2, int *iCom
|
|||
|
||||
if( filename1 && filename2 )
|
||||
{
|
||||
long ft1 = FS_FileTime( filename1, false );
|
||||
long ft2 = FS_FileTime( filename2, false );
|
||||
int ft1 = FS_FileTime( filename1, false );
|
||||
int ft2 = FS_FileTime( filename2, false );
|
||||
|
||||
// one of files is missing
|
||||
if( ft1 == -1 || ft2 == -1 )
|
||||
|
|
|
@ -89,7 +89,7 @@ XASH SPECIFIC - sort of hack that works only in Xash3D not in GoldSrc
|
|||
#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 Msg or MsgDev
|
||||
#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
|
||||
|
@ -103,6 +103,10 @@ XASH SPECIFIC - sort of hack that works only in Xash3D not in GoldSrc
|
|||
#define FBitSet( iBitVector, bit ) ((iBitVector) & (bit))
|
||||
|
||||
#ifndef __cplusplus
|
||||
#ifdef NULL
|
||||
#undef NULL
|
||||
#endif
|
||||
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
|
@ -116,6 +120,37 @@ XASH SPECIFIC - sort of hack that works only in Xash3D not in GoldSrc
|
|||
#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];
|
||||
|
@ -199,10 +234,13 @@ typedef enum
|
|||
#define MAX_STATIC_ENTITIES 3096 // static entities that moved on the client when level is spawn
|
||||
|
||||
// filesystem flags
|
||||
#define FS_STATIC_PATH 1 // FS_ClearSearchPath will be ignore this path
|
||||
#define FS_NOWRITE_PATH 2 // default behavior - last added gamedir set as writedir. This flag disables it
|
||||
#define FS_GAMEDIR_PATH 4 // just a marker for gamedir path
|
||||
#define FS_CUSTOM_PATH 8 // custom directory
|
||||
#define FS_STATIC_PATH ( 1U << 0 ) // FS_ClearSearchPath will be ignore this path
|
||||
#define FS_NOWRITE_PATH ( 1U << 1 ) // default behavior - last added gamedir set as writedir. This flag disables it
|
||||
#define FS_GAMEDIR_PATH ( 1U << 2 ) // just a marker for gamedir path
|
||||
#define FS_CUSTOM_PATH ( 1U << 3 ) // custom directory
|
||||
#define FS_GAMERODIR_PATH ( 1U << 4 ) // caseinsensitive
|
||||
|
||||
#define FS_GAMEDIRONLY_SEARCH_FLAGS ( FS_GAMEDIR_PATH | FS_CUSTOM_PATH | FS_GAMERODIR_PATH )
|
||||
|
||||
#define GI SI.GameInfo
|
||||
#define FS_Gamedir() SI.GameInfo->gamefolder
|
||||
|
@ -273,9 +311,11 @@ typedef struct gameinfo_s
|
|||
int gamemode;
|
||||
qboolean secure; // prevent to console acess
|
||||
qboolean nomodels; // don't let player to choose model (use player.mdl always)
|
||||
qboolean noskills; // disable skill menu selection
|
||||
|
||||
char sp_entity[32]; // e.g. info_player_start
|
||||
char mp_entity[32]; // e.g. info_player_deathmatch
|
||||
char mp_filter[32]; // filtering multiplayer-maps
|
||||
|
||||
char ambientsound[NUM_AMBIENTS][MAX_QPATH]; // quake ambient sounds
|
||||
|
||||
|
@ -287,6 +327,8 @@ typedef struct gameinfo_s
|
|||
char game_dll_linux[64]; // custom path for game.dll
|
||||
char game_dll_osx[64]; // custom path for game.dll
|
||||
char client_lib[64]; // custom name of client library
|
||||
|
||||
qboolean added;
|
||||
} gameinfo_t;
|
||||
|
||||
typedef enum
|
||||
|
@ -364,6 +406,15 @@ typedef enum
|
|||
|
||||
#include "net_ws.h"
|
||||
|
||||
// console field
|
||||
typedef struct
|
||||
{
|
||||
string buffer;
|
||||
int cursor;
|
||||
int scroll;
|
||||
int widthInChars;
|
||||
} field_t;
|
||||
|
||||
typedef struct host_redirect_s
|
||||
{
|
||||
rdtype_t target;
|
||||
|
@ -425,6 +476,7 @@ typedef struct
|
|||
typedef struct host_parm_s
|
||||
{
|
||||
HINSTANCE hInst;
|
||||
HANDLE hMutex;
|
||||
|
||||
host_status_t status; // global host state
|
||||
game_status_t game; // game manager
|
||||
|
@ -435,6 +487,7 @@ typedef struct host_parm_s
|
|||
string finalmsg; // server shutdown final message
|
||||
string downloadfile; // filename to be downloading
|
||||
int downloadcount; // how many files remain to downloading
|
||||
char deferred_cmd[128]; // deferred commands
|
||||
host_redirect_t rd; // remote console
|
||||
|
||||
// command line parms
|
||||
|
@ -483,6 +536,7 @@ typedef struct host_parm_s
|
|||
qboolean renderinfo_changed;
|
||||
|
||||
char rootdir[256]; // member root directory
|
||||
char rodir[256]; // readonly root
|
||||
char gamefolder[MAX_QPATH]; // it's a default gamefolder
|
||||
byte *imagepool; // imagelib mempool
|
||||
byte *soundpool; // soundlib mempool
|
||||
|
@ -510,8 +564,8 @@ void FS_Rescan( void );
|
|||
void FS_Shutdown( void );
|
||||
void FS_ClearSearchPath( void );
|
||||
void FS_AllowDirectPaths( qboolean enable );
|
||||
void FS_AddGameDirectory( const char *dir, int flags );
|
||||
void FS_AddGameHierarchy( const char *dir, int flags );
|
||||
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 );
|
||||
|
@ -522,9 +576,9 @@ 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, long *filesizeptr, qboolean gamedironly );
|
||||
byte *FS_LoadDirectFile( const char *path, long *filesizeptr );
|
||||
qboolean FS_WriteFile( const char *filename, const void *data, long len );
|
||||
byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly );
|
||||
byte *FS_LoadDirectFile( const char *path, fs_offset_t *filesizeptr );
|
||||
qboolean FS_WriteFile( const char *filename, const void *data, fs_offset_t len );
|
||||
qboolean COM_ParseVector( char **pfile, float *v, size_t size );
|
||||
void COM_NormalizeAngles( vec3_t angles );
|
||||
int COM_FileSize( const char *filename );
|
||||
|
@ -534,14 +588,14 @@ 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 );
|
||||
long FS_Write( file_t *file, const void *data, size_t datasize );
|
||||
long FS_Read( file_t *file, void *buffer, size_t buffersize );
|
||||
fs_offset_t FS_Write( file_t *file, const void *data, size_t datasize );
|
||||
fs_offset_t FS_Read( file_t *file, void *buffer, size_t buffersize );
|
||||
int FS_VPrintf( file_t *file, const char *format, va_list ap );
|
||||
int FS_Seek( file_t *file, long offset, int whence );
|
||||
int FS_Seek( file_t *file, fs_offset_t offset, int whence );
|
||||
int FS_Gets( file_t *file, byte *string, size_t bufsize );
|
||||
int FS_Printf( file_t *file, const char *format, ... ) _format( 2 );
|
||||
long FS_FileSize( const char *filename, qboolean gamedironly );
|
||||
long FS_FileTime( const char *filename, qboolean gamedironly );
|
||||
fs_offset_t FS_FileSize( const char *filename, qboolean gamedironly );
|
||||
int FS_FileTime( const char *filename, qboolean gamedironly );
|
||||
int FS_Print( file_t *file, const char *msg );
|
||||
qboolean FS_Rename( const char *oldname, const char *newname );
|
||||
int FS_FileExists( const char *filename, int gamedironly );
|
||||
|
@ -550,11 +604,11 @@ 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 );
|
||||
long FS_Tell( file_t *file );
|
||||
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 );
|
||||
long FS_FileLength( file_t *f );
|
||||
fs_offset_t FS_FileLength( file_t *f );
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
@ -566,7 +620,7 @@ NOTE: number at end of pixelformat name it's a total bitscount e.g. PF_RGB_24 ==
|
|||
========================================================================
|
||||
*/
|
||||
#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)
|
||||
#define ImageDXT( type ) (type == PF_DXT1 || type == PF_DXT3 || type == PF_DXT5 || type == PF_ATI2)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -580,6 +634,7 @@ typedef enum
|
|||
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;
|
||||
|
||||
|
@ -637,7 +692,7 @@ typedef enum
|
|||
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,
|
||||
// reserved
|
||||
IMAGE_EMBOSS = BIT(19), // apply emboss mapping
|
||||
IMAGE_RESAMPLE = BIT(20), // resample image to specified dims
|
||||
// reserved
|
||||
// reserved
|
||||
|
@ -648,16 +703,6 @@ typedef enum
|
|||
IMAGE_REMAP = BIT(27), // interpret width and height as top and bottom color
|
||||
} imgFlags_t;
|
||||
|
||||
// ordering is important!
|
||||
typedef enum
|
||||
{
|
||||
BLUR_FILTER = 0,
|
||||
BLUR_FILTER2,
|
||||
EDGE_FILTER,
|
||||
EMBOSS_FILTER,
|
||||
NUM_FILTERS,
|
||||
} pixfilter_t;
|
||||
|
||||
typedef struct rgbdata_s
|
||||
{
|
||||
word width; // image width
|
||||
|
@ -673,21 +718,6 @@ typedef struct rgbdata_s
|
|||
size_t size; // for bounds checking
|
||||
} rgbdata_t;
|
||||
|
||||
// imgfilter processing flags
|
||||
typedef enum
|
||||
{
|
||||
FILTER_GRAYSCALE = BIT(0),
|
||||
} flFlags_t;
|
||||
|
||||
typedef struct imgfilter_s
|
||||
{
|
||||
int filter; // pixfilter_t
|
||||
float factor; // filter factor value
|
||||
float bias; // filter bias value
|
||||
flFlags_t flags; // filter additional flags
|
||||
uint blendFunc; // blending mode
|
||||
} imgfilter_t;
|
||||
|
||||
//
|
||||
// imagelib
|
||||
//
|
||||
|
@ -699,12 +729,15 @@ qboolean FS_SaveImage( const char *filename, rgbdata_t *pix );
|
|||
rgbdata_t *FS_CopyImage( rgbdata_t *in );
|
||||
void FS_FreeImage( rgbdata_t *pack );
|
||||
extern const bpc_desc_t PFDesc[]; // image get pixelformat
|
||||
qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, imgfilter_t *filter );
|
||||
qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, float bumpscale );
|
||||
void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end, int pal_size );
|
||||
void Image_PaletteTranslate( byte *palSrc, int top, int bottom, int pal_size );
|
||||
void Image_SetForceFlags( uint flags ); // set image force flags on loading
|
||||
size_t Image_DXTGetLinearSize( int type, int width, int height, int depth );
|
||||
qboolean Image_CustomPalette( void );
|
||||
void Image_ClearForceFlags( void );
|
||||
void Image_SetMDLPointer( byte *p );
|
||||
void Image_CheckPaletteQ1( void );
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
@ -764,9 +797,9 @@ wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size )
|
|||
void FS_FreeSound( wavdata_t *pack );
|
||||
stream_t *FS_OpenStream( const char *filename );
|
||||
wavdata_t *FS_StreamInfo( stream_t *stream );
|
||||
long FS_ReadStream( stream_t *stream, int bytes, void *buffer );
|
||||
long FS_SetStreamPos( stream_t *stream, long newpos );
|
||||
long FS_GetStreamPos( stream_t *stream );
|
||||
int FS_ReadStream( stream_t *stream, int bytes, void *buffer );
|
||||
int FS_SetStreamPos( stream_t *stream, int newpos );
|
||||
int FS_GetStreamPos( stream_t *stream );
|
||||
void FS_FreeStream( stream_t *stream );
|
||||
qboolean Sound_Process( wavdata_t **wav, int rate, int width, uint flags );
|
||||
uint Sound_GetApproxWavePlayLen( const char *filepath );
|
||||
|
@ -783,8 +816,9 @@ const char *Q_buildcommit( void );
|
|||
//
|
||||
// host.c
|
||||
//
|
||||
qboolean Host_IsQuakeCompatible( void );
|
||||
void EXPORT Host_Shutdown( void );
|
||||
int Host_CompareFileTime( long ft1, long ft2 );
|
||||
int Host_CompareFileTime( int ft1, int ft2 );
|
||||
void Host_NewInstance( const char *name, const char *finalmsg );
|
||||
void Host_EndGame( qboolean abort, const char *message, ... ) _format( 2 );
|
||||
void Host_AbortCurrentFrame( void );
|
||||
|
@ -842,7 +876,7 @@ cvar_t *pfnCvar_RegisterClientVariable( const char *szName, const char *szValue,
|
|||
cvar_t *pfnCvar_RegisterGameUIVariable( const char *szName, const char *szValue, int flags );
|
||||
char *COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize );
|
||||
void COM_HexConvert( const char *pszInput, int nInputLength, byte *pOutput );
|
||||
int COM_SaveFile( const char *filename, const void *data, long len );
|
||||
int COM_SaveFile( const char *filename, const void *data, int len );
|
||||
byte* COM_LoadFileForMe( const char *filename, int *pLength );
|
||||
qboolean COM_IsSafeFileToDownload( const char *filename );
|
||||
cvar_t *pfnCVarGetPointer( const char *szVarName );
|
||||
|
@ -886,10 +920,19 @@ void pfnResetTutorMessageDecayData( void );
|
|||
|
||||
==============================================================
|
||||
*/
|
||||
#define Z_Malloc( size ) Mem_Alloc( host.mempool, size )
|
||||
#define Z_Malloc( size ) Mem_Malloc( host.mempool, size )
|
||||
#define Z_Calloc( size ) Mem_Calloc( host.mempool, size )
|
||||
#define Z_Realloc( ptr, size ) Mem_Realloc( host.mempool, ptr, size )
|
||||
#define Z_Free( ptr ) if( ptr != NULL ) Mem_Free( ptr )
|
||||
|
||||
//
|
||||
// con_utils.c
|
||||
//
|
||||
qboolean Cmd_AutocompleteName( const char *source, char *buffer, size_t bufsize );
|
||||
void Con_CompleteCommand( field_t *field );
|
||||
void Cmd_AutoComplete( char *complete_string );
|
||||
void Cmd_AutoCompleteClear( void );
|
||||
|
||||
//
|
||||
// crclib.c
|
||||
//
|
||||
|
@ -953,9 +996,9 @@ void Key_EnableTextInput( qboolean enable, qboolean force );
|
|||
#include "avi/avi.h"
|
||||
|
||||
// shared calls
|
||||
struct physent_s;
|
||||
typedef struct sv_client_s sv_client_t;
|
||||
typedef struct sizebuf_s sizebuf_t;
|
||||
typedef struct physent_s physent_t;
|
||||
qboolean CL_IsInGame( void );
|
||||
qboolean CL_IsInMenu( void );
|
||||
qboolean CL_IsInConsole( void );
|
||||
|
@ -963,6 +1006,7 @@ qboolean CL_IsThirdPerson( void );
|
|||
qboolean CL_IsIntermission( void );
|
||||
qboolean CL_Initialized( void );
|
||||
char *CL_Userinfo( void );
|
||||
void CL_LegacyUpdateInfo( void );
|
||||
void CL_CharEvent( int key );
|
||||
qboolean CL_DisableVisibility( void );
|
||||
int CL_PointContents( const vec3_t point );
|
||||
|
@ -977,7 +1021,7 @@ struct cmdalias_s *Cmd_AliasGetList( void );
|
|||
char *Cmd_GetName( struct cmd_s *cmd );
|
||||
struct pmtrace_s *PM_TraceLine( float *start, float *end, int flags, int usehull, int ignore_pe );
|
||||
void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float attn, int flags, int pitch );
|
||||
void SV_StartMusic( const char *curtrack, const char *looptrack, long position );
|
||||
void SV_StartMusic( const char *curtrack, const char *looptrack, int position );
|
||||
void SV_CreateDecal( sizebuf_t *msg, const float *origin, int decalIndex, int entityIndex, int modelIndex, int flags, float scale );
|
||||
void Log_Printf( const char *fmt, ... ) _format( 1 );
|
||||
struct sizebuf_s *SV_GetReliableDatagram( void );
|
||||
|
@ -998,6 +1042,7 @@ void SV_DrawDebugTriangles( void );
|
|||
void SV_DrawOrthoTriangles( void );
|
||||
double CL_GetDemoFramerate( void );
|
||||
qboolean UI_CreditsActive( void );
|
||||
void CL_StopPlayback( void );
|
||||
void CL_ExtraUpdate( void );
|
||||
int CL_GetMaxClients( void );
|
||||
int SV_GetMaxClients( void );
|
||||
|
@ -1010,8 +1055,8 @@ qboolean SV_Initialized( void );
|
|||
qboolean CL_LoadProgs( const char *name );
|
||||
int SV_GetSaveComment( const char *savename, char *comment );
|
||||
qboolean SV_NewGame( const char *mapName, qboolean loadGame );
|
||||
void SV_ClipPMoveToEntity( physent_t *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, struct pmtrace_s *tr );
|
||||
void CL_ClipPMoveToEntity( physent_t *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, struct pmtrace_s *tr );
|
||||
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 );
|
||||
|
@ -1033,7 +1078,7 @@ void SCR_Init( void );
|
|||
void SCR_UpdateScreen( void );
|
||||
void SCR_BeginLoadingPlaque( qboolean is_background );
|
||||
void SCR_CheckStartupVids( void );
|
||||
long SCR_GetAudioChunk( char *rawdata, long length );
|
||||
int SCR_GetAudioChunk( char *rawdata, int length );
|
||||
wavdata_t *SCR_GetMovieInfo( void );
|
||||
void SCR_Shutdown( void );
|
||||
void Con_Print( const char *txt );
|
||||
|
@ -1051,9 +1096,7 @@ void Info_WriteVars( file_t *f );
|
|||
void Info_Print( const char *s );
|
||||
void Cmd_WriteVariables( file_t *f );
|
||||
int Cmd_CheckMapsList( int fRefresh );
|
||||
qboolean Cmd_AutocompleteName( const char *source, char *buffer, size_t bufsize );
|
||||
void Cmd_AutoComplete( char *complete_string );
|
||||
void COM_SetRandomSeed( long lSeed );
|
||||
void COM_SetRandomSeed( int lSeed );
|
||||
int COM_RandomLong( int lMin, int lMax );
|
||||
float COM_RandomFloat( float fMin, float fMax );
|
||||
qboolean LZSS_IsCompressed( const byte *source );
|
||||
|
@ -1069,7 +1112,6 @@ void Cmd_Null_f( void );
|
|||
// soundlib shared exports
|
||||
qboolean S_Init( void );
|
||||
void S_Shutdown( void );
|
||||
void S_Activate( qboolean active );
|
||||
void S_StopSound( int entnum, int channel, const char *soundname );
|
||||
int S_GetCurrentStaticSounds( soundlist_t *pout, int size );
|
||||
void S_StopBackgroundTrack( void );
|
||||
|
@ -1095,6 +1137,13 @@ typedef struct sentenceEntry_ sentenceEntry_s;
|
|||
sequenceEntry_s *Sequence_Get( const char *fileName, const char *entryName );
|
||||
sentenceEntry_s *Sequence_PickSentence( const char *groupName, int pickMethod, int *picked );
|
||||
|
||||
//
|
||||
// masterlist.c
|
||||
//
|
||||
void NET_InitMasters( void );
|
||||
void NET_SaveMasters( void );
|
||||
qboolean NET_SendToMasters( netsrc_t sock, size_t len, const void *data );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -20,16 +20,32 @@ GNU General Public License for more details.
|
|||
|
||||
extern convar_t *con_gamemaps;
|
||||
|
||||
#define CON_MAXCMDS 4096 // auto-complete intermediate list
|
||||
|
||||
typedef struct autocomplete_list_s
|
||||
{
|
||||
const char *name;
|
||||
qboolean (*func)( const char *s, char *name, int length );
|
||||
} autocomplete_list_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// console auto-complete
|
||||
string shortestMatch;
|
||||
field_t *completionField; // con.input or dedicated server fake field-line
|
||||
const char *completionString;
|
||||
const char *completionBuffer;
|
||||
char *cmds[CON_MAXCMDS];
|
||||
int matchCount;
|
||||
} con_autocomplete_t;
|
||||
|
||||
static con_autocomplete_t con;
|
||||
|
||||
/*
|
||||
=======================================================================
|
||||
|
||||
FILENAME AUTOCOMPLETION
|
||||
|
||||
=======================================================================
|
||||
*/
|
||||
/*
|
||||
|
@ -102,7 +118,7 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
|
|||
if( !ents && lumplen >= 10 )
|
||||
{
|
||||
FS_Seek( f, lumpofs, SEEK_SET );
|
||||
ents = (char *)Mem_Alloc( host.mempool, lumplen + 1 );
|
||||
ents = (char *)Mem_Calloc( host.mempool, lumplen + 1 );
|
||||
FS_Read( f, ents, lumplen );
|
||||
}
|
||||
|
||||
|
@ -191,7 +207,8 @@ qboolean Cmd_GetDemoList( const char *s, char *completedname, int length )
|
|||
string matchbuf;
|
||||
int i, numdems;
|
||||
|
||||
t = FS_Search( va( "demos/%s*.dem", s ), true, true ); // lookup only in gamedir
|
||||
// lookup only in gamedir
|
||||
t = FS_Search( va( "%s*.dem", s ), true, true );
|
||||
if( !t ) return false;
|
||||
|
||||
COM_FileBase( t->filenames[0], matchbuf );
|
||||
|
@ -669,7 +686,9 @@ qboolean Cmd_GetCDList( const char *s, char *completedname, int length )
|
|||
|
||||
qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
|
||||
{
|
||||
qboolean use_filter = false;
|
||||
byte buf[MAX_SYSPATH];
|
||||
string mpfilter;
|
||||
char *buffer;
|
||||
string result;
|
||||
int i, size;
|
||||
|
@ -677,11 +696,10 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
|
|||
file_t *f;
|
||||
|
||||
if( FS_FileSize( "maps.lst", onlyingamedir ) > 0 && !fRefresh )
|
||||
{
|
||||
MsgDev( D_NOTE, "maps.lst is exist: %s\n", onlyingamedir ? "basedir" : "gamedir" );
|
||||
return true; // exist
|
||||
}
|
||||
|
||||
// setup mpfilter
|
||||
Q_snprintf( mpfilter, sizeof( mpfilter ), "maps/%s", GI->mp_filter );
|
||||
t = FS_Search( "maps/*.bsp", false, onlyingamedir );
|
||||
|
||||
if( !t )
|
||||
|
@ -694,7 +712,8 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
|
|||
return false;
|
||||
}
|
||||
|
||||
buffer = Mem_Alloc( host.mempool, t->numfilenames * 2 * sizeof( result ));
|
||||
buffer = Mem_Calloc( host.mempool, t->numfilenames * 2 * sizeof( result ));
|
||||
use_filter = Q_strlen( GI->mp_filter ) ? true : false;
|
||||
|
||||
for( i = 0; i < t->numfilenames; i++ )
|
||||
{
|
||||
|
@ -705,6 +724,9 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
|
|||
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "bsp" ))
|
||||
continue;
|
||||
|
||||
if( use_filter && !Q_strnicmp( t->filenames[i], mpfilter, Q_strlen( mpfilter )))
|
||||
continue;
|
||||
|
||||
f = FS_Open( t->filenames[i], "rb", onlyingamedir );
|
||||
COM_FileBase( t->filenames[i], mapname );
|
||||
|
||||
|
@ -736,7 +758,7 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
|
|||
if( !ents && lumplen >= 10 )
|
||||
{
|
||||
FS_Seek( f, lumpofs, SEEK_SET );
|
||||
ents = Z_Malloc( lumplen + 1 );
|
||||
ents = Z_Calloc( lumplen + 1 );
|
||||
FS_Read( f, ents, lumplen );
|
||||
}
|
||||
|
||||
|
@ -762,7 +784,7 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
|
|||
else if( !Q_strcmp( token, "classname" ))
|
||||
{
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
if( !Q_strcmp( token, GI->mp_entity ))
|
||||
if( !Q_strcmp( token, GI->mp_entity ) || use_filter )
|
||||
num_spawnpoints++;
|
||||
}
|
||||
if( num_spawnpoints ) break; // valid map
|
||||
|
@ -810,6 +832,7 @@ int Cmd_CheckMapsList( int fRefresh )
|
|||
autocomplete_list_t cmd_list[] =
|
||||
{
|
||||
{ "map_background", Cmd_GetMapList },
|
||||
{ "changelevel2", Cmd_GetMapList },
|
||||
{ "changelevel", Cmd_GetMapList },
|
||||
{ "playdemo", Cmd_GetDemoList, },
|
||||
{ "timedemo", Cmd_GetDemoList, },
|
||||
|
@ -869,6 +892,268 @@ qboolean Cmd_AutocompleteName( const char *source, char *buffer, size_t bufsize
|
|||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_AddCommandToList
|
||||
|
||||
===============
|
||||
*/
|
||||
static void Con_AddCommandToList( const char *s, const char *unused1, const char *unused2, void *unused3 )
|
||||
{
|
||||
if( *s == '@' ) return; // never show system cvars or cmds
|
||||
if( con.matchCount >= CON_MAXCMDS ) return; // list is full
|
||||
|
||||
if( Q_strnicmp( s, con.completionString, Q_strlen( con.completionString ) ) )
|
||||
return; // no match
|
||||
|
||||
con.cmds[con.matchCount++] = copystring( s );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Con_SortCmds
|
||||
=================
|
||||
*/
|
||||
static int Con_SortCmds( const char **arg1, const char **arg2 )
|
||||
{
|
||||
return Q_stricmp( *arg1, *arg2 );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_PrintCmdMatches
|
||||
===============
|
||||
*/
|
||||
static void Con_PrintCmdMatches( const char *s, const char *unused1, const char *m, void *unused2 )
|
||||
{
|
||||
if( !Q_strnicmp( s, con.shortestMatch, Q_strlen( con.shortestMatch ) ) )
|
||||
{
|
||||
if( COM_CheckString( m ) ) Con_Printf( " %s ^3\"%s\"\n", s, m );
|
||||
else Con_Printf( " %s\n", s ); // variable or command without description
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_PrintCvarMatches
|
||||
===============
|
||||
*/
|
||||
static void Con_PrintCvarMatches( const char *s, const char *value, const char *m, void *unused2 )
|
||||
{
|
||||
if( !Q_strnicmp( s, con.shortestMatch, Q_strlen( con.shortestMatch ) ) )
|
||||
{
|
||||
if( COM_CheckString( m ) ) Con_Printf( " %s (%s) ^3\"%s\"\n", s, value, m );
|
||||
else Con_Printf( " %s (%s)\n", s, value ); // variable or command without description
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_ConcatRemaining
|
||||
===============
|
||||
*/
|
||||
static void Con_ConcatRemaining( const char *src, const char *start )
|
||||
{
|
||||
const char *arg;
|
||||
int i;
|
||||
|
||||
arg = Q_strstr( src, start );
|
||||
|
||||
if( !arg )
|
||||
{
|
||||
for( i = 1; i < Cmd_Argc(); i++ )
|
||||
{
|
||||
Q_strncat( con.completionField->buffer, " ", sizeof( con.completionField->buffer ) );
|
||||
arg = Cmd_Argv( i );
|
||||
while( *arg )
|
||||
{
|
||||
if( *arg == ' ' )
|
||||
{
|
||||
Q_strncat( con.completionField->buffer, "\"", sizeof( con.completionField->buffer ) );
|
||||
break;
|
||||
}
|
||||
arg++;
|
||||
}
|
||||
|
||||
Q_strncat( con.completionField->buffer, Cmd_Argv( i ), sizeof( con.completionField->buffer ) );
|
||||
if( *arg == ' ' ) Q_strncat( con.completionField->buffer, "\"", sizeof( con.completionField->buffer ) );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
arg += Q_strlen( start );
|
||||
Q_strncat( con.completionField->buffer, arg, sizeof( con.completionField->buffer ) );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_CompleteCommand
|
||||
|
||||
perform Tab expansion
|
||||
===============
|
||||
*/
|
||||
void Con_CompleteCommand( field_t *field )
|
||||
{
|
||||
field_t temp;
|
||||
string filename;
|
||||
qboolean nextcmd;
|
||||
int i;
|
||||
|
||||
// setup the completion field
|
||||
con.completionField = field;
|
||||
|
||||
// only look at the first token for completion purposes
|
||||
Cmd_TokenizeString( con.completionField->buffer );
|
||||
|
||||
nextcmd = (con.completionField->buffer[Q_strlen( con.completionField->buffer ) - 1] == ' ') ? true : false;
|
||||
|
||||
con.completionString = Cmd_Argv( 0 );
|
||||
con.completionBuffer = Cmd_Argv( 1 );
|
||||
|
||||
// skip backslash
|
||||
while( *con.completionString && (*con.completionString == '\\' || *con.completionString == '/') )
|
||||
con.completionString++;
|
||||
|
||||
// skip backslash
|
||||
while( *con.completionBuffer && (*con.completionBuffer == '\\' || *con.completionBuffer == '/') )
|
||||
con.completionBuffer++;
|
||||
|
||||
if( !Q_strlen( con.completionString ) )
|
||||
return;
|
||||
|
||||
// free the old autocomplete list
|
||||
for( i = 0; i < con.matchCount; i++ )
|
||||
{
|
||||
if( con.cmds[i] != NULL )
|
||||
{
|
||||
Mem_Free( con.cmds[i] );
|
||||
con.cmds[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
con.matchCount = 0;
|
||||
con.shortestMatch[0] = 0;
|
||||
|
||||
// find matching commands and variables
|
||||
Cmd_LookupCmds( NULL, NULL, Con_AddCommandToList );
|
||||
Cvar_LookupVars( 0, NULL, NULL, Con_AddCommandToList );
|
||||
|
||||
if( !con.matchCount ) return; // no matches
|
||||
|
||||
memcpy( &temp, con.completionField, sizeof( field_t ) );
|
||||
|
||||
// autocomplete second arg
|
||||
if( (Cmd_Argc() == 2) || ((Cmd_Argc() == 1) && nextcmd) )
|
||||
{
|
||||
if( !Q_strlen( con.completionBuffer ) )
|
||||
return;
|
||||
|
||||
if( Cmd_AutocompleteName( con.completionBuffer, filename, sizeof( filename ) ) )
|
||||
{
|
||||
Q_sprintf( con.completionField->buffer, "%s %s", Cmd_Argv( 0 ), filename );
|
||||
con.completionField->cursor = Q_strlen( con.completionField->buffer );
|
||||
}
|
||||
|
||||
// don't adjusting cursor pos if we nothing found
|
||||
return;
|
||||
}
|
||||
else if( Cmd_Argc() >= 3 )
|
||||
{
|
||||
// disable autocomplete for all next args
|
||||
return;
|
||||
}
|
||||
|
||||
if( con.matchCount == 1 )
|
||||
{
|
||||
Q_sprintf( con.completionField->buffer, "\\%s", con.cmds[0] );
|
||||
if( Cmd_Argc() == 1 ) Q_strncat( con.completionField->buffer, " ", sizeof( con.completionField->buffer ) );
|
||||
else Con_ConcatRemaining( temp.buffer, con.completionString );
|
||||
con.completionField->cursor = Q_strlen( con.completionField->buffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
char *first, *last;
|
||||
int len = 0;
|
||||
|
||||
qsort( con.cmds, con.matchCount, sizeof( char* ), Con_SortCmds );
|
||||
|
||||
// find the number of matching characters between the first and
|
||||
// the last element in the list and copy it
|
||||
first = con.cmds[0];
|
||||
last = con.cmds[con.matchCount - 1];
|
||||
|
||||
while( *first && *last && Q_tolower( *first ) == Q_tolower( *last ) )
|
||||
{
|
||||
first++;
|
||||
last++;
|
||||
|
||||
con.shortestMatch[len] = con.cmds[0][len];
|
||||
len++;
|
||||
}
|
||||
con.shortestMatch[len] = 0;
|
||||
|
||||
// multiple matches, complete to shortest
|
||||
Q_sprintf( con.completionField->buffer, "\\%s", con.shortestMatch );
|
||||
con.completionField->cursor = Q_strlen( con.completionField->buffer );
|
||||
Con_ConcatRemaining( temp.buffer, con.completionString );
|
||||
|
||||
Con_Printf( "]%s\n", con.completionField->buffer );
|
||||
|
||||
// run through again, printing matches
|
||||
Cmd_LookupCmds( NULL, NULL, Con_PrintCmdMatches );
|
||||
Cvar_LookupVars( 0, NULL, NULL, Con_PrintCvarMatches );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=========
|
||||
Cmd_AutoComplete
|
||||
|
||||
NOTE: input string must be equal or longer than MAX_STRING
|
||||
=========
|
||||
*/
|
||||
void Cmd_AutoComplete( char *complete_string )
|
||||
{
|
||||
field_t input;
|
||||
|
||||
if( !complete_string || !*complete_string )
|
||||
return;
|
||||
|
||||
// setup input
|
||||
Q_strncpy( input.buffer, complete_string, sizeof( input.buffer ) );
|
||||
input.cursor = input.scroll = 0;
|
||||
|
||||
Con_CompleteCommand( &input );
|
||||
|
||||
// setup output
|
||||
if( input.buffer[0] == '\\' || input.buffer[0] == '/' )
|
||||
Q_strncpy( complete_string, input.buffer + 1, sizeof( input.buffer ) );
|
||||
else Q_strncpy( complete_string, input.buffer, sizeof( input.buffer ) );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_AutoCompleteClear
|
||||
|
||||
============
|
||||
*/
|
||||
void Cmd_AutoCompleteClear( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
// free the old autocomplete list
|
||||
for( i = 0; i < con.matchCount; i++ )
|
||||
{
|
||||
if( con.cmds[i] != NULL )
|
||||
{
|
||||
Mem_Free( con.cmds[i] );
|
||||
con.cmds[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
con.matchCount = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_WriteVariables
|
||||
|
@ -907,6 +1192,23 @@ void Cmd_WriteOpenGLVariables( file_t *f )
|
|||
}
|
||||
|
||||
#ifndef XASH_DEDICATED
|
||||
|
||||
|
||||
#define CFG_END(f,x) \
|
||||
if( FS_Printf( f,"// end of " x "\n" ) >= (int)sizeof( "// end of " x "\n" ) - 2 )\
|
||||
{ \
|
||||
FS_Close( f );\
|
||||
FS_Delete( x ".bak" ); \
|
||||
FS_Rename( x, x ".bak" ); \
|
||||
FS_Delete( x ); \
|
||||
FS_Rename( x ".new", x );\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
FS_Close( f );\
|
||||
Con_Reportf( S_ERROR "could not update " x "\n" );\
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Host_WriteConfig
|
||||
|
@ -920,12 +1222,13 @@ void Host_WriteConfig( void )
|
|||
kbutton_t *jlook = NULL;
|
||||
file_t *f;
|
||||
|
||||
if( !clgame.hInstance ) return;
|
||||
if( !clgame.hInstance || Sys_CheckParm( "-nowriteconfig" ) ) return;
|
||||
|
||||
MsgDev( D_NOTE, "Host_WriteConfig()\n" );
|
||||
f = FS_Open( "config.cfg", "w", false );
|
||||
|
||||
f = FS_Open( "config.cfg.new", "w", false );
|
||||
if( f )
|
||||
{
|
||||
Con_Reportf( "Host_WriteConfig()\n" );
|
||||
FS_Printf( f, "//=======================================================================\n");
|
||||
FS_Printf( f, "//\t\t\tCopyright XashXT Group %s (C)\n", Q_timestamp( TIME_YEAR_ONLY ));
|
||||
FS_Printf( f, "//\t\t\tconfig.cfg - archive of cvars\n" );
|
||||
|
@ -946,13 +1249,14 @@ void Host_WriteConfig( void )
|
|||
if( jlook && ( jlook->state & 1 ))
|
||||
FS_Printf( f, "+jlook\n" );
|
||||
|
||||
FS_Printf( f, "exec userconfig.cfg" );
|
||||
FS_Printf( f, "exec userconfig.cfg\n" );
|
||||
|
||||
FS_Close( f );
|
||||
CFG_END( f, "config.cfg" );
|
||||
}
|
||||
else MsgDev( D_ERROR, "Couldn't write config.cfg.\n" );
|
||||
else Con_DPrintf( S_ERROR "Couldn't write config.cfg.\n" );
|
||||
|
||||
NET_SaveMasters();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
===============
|
||||
|
@ -964,23 +1268,34 @@ save serverinfo variables into server.cfg (using for dedicated server too)
|
|||
void Host_WriteServerConfig( const char *name )
|
||||
{
|
||||
file_t *f;
|
||||
string oldconfigfile, newconfigfile;
|
||||
|
||||
Q_snprintf( oldconfigfile, MAX_STRING, "%s.bak", name );
|
||||
Q_snprintf( newconfigfile, MAX_STRING, "%s.new", name );
|
||||
|
||||
SV_InitGameProgs(); // collect user variables
|
||||
|
||||
// FIXME: move this out until menu parser is done
|
||||
CSCR_LoadDefaultCVars( "settings.scr" );
|
||||
|
||||
if(( f = FS_Open( name, "w", false )) != NULL )
|
||||
if(( f = FS_Open( newconfigfile, "w", false )) != NULL )
|
||||
{
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
FS_Printf( f, "//\t\t\tCopyright XashXT Group %s (C)\n", Q_timestamp( TIME_YEAR_ONLY ));
|
||||
FS_Printf( f, "//\t\tgame.cfg - multiplayer server temporare config\n" );
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
|
||||
Cvar_WriteVariables( f, FCVAR_SERVER );
|
||||
CSCR_WriteGameCVars( f, "settings.scr" );
|
||||
|
||||
FS_Close( f );
|
||||
|
||||
FS_Rename( name, oldconfigfile );
|
||||
FS_Delete( name );
|
||||
FS_Rename( newconfigfile, name );
|
||||
FS_Delete( oldconfigfile );
|
||||
}
|
||||
else MsgDev( D_ERROR, "Couldn't write %s.\n", name );
|
||||
else Con_DPrintf( S_ERROR "Couldn't write %s.\n", name );
|
||||
|
||||
SV_FreeGameProgs(); // release progs with all variables
|
||||
}
|
||||
|
@ -996,19 +1311,22 @@ void Host_WriteOpenGLConfig( void )
|
|||
{
|
||||
file_t *f;
|
||||
|
||||
MsgDev( D_NOTE, "Host_WriteGLConfig()\n" );
|
||||
f = FS_Open( "opengl.cfg", "w", false );
|
||||
if( Sys_CheckParm( "-nowriteconfig" ) )
|
||||
return;
|
||||
|
||||
f = FS_Open( "opengl.cfg.new", "w", false );
|
||||
if( f )
|
||||
{
|
||||
Con_Reportf( "Host_WriteGLConfig()\n" );
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
FS_Printf( f, "//\t\t\tCopyright XashXT Group %s (C)\n", Q_timestamp( TIME_YEAR_ONLY ));
|
||||
FS_Printf( f, "//\t\t opengl.cfg - archive of opengl extension cvars\n");
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
FS_Printf( f, "\n" );
|
||||
Cmd_WriteOpenGLVariables( f );
|
||||
FS_Close( f );
|
||||
CFG_END( f, "opengl.cfg" );
|
||||
}
|
||||
else MsgDev( D_ERROR, "can't update opengl.cfg.\n" );
|
||||
else Con_DPrintf( S_ERROR "can't update opengl.cfg.\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1022,19 +1340,23 @@ void Host_WriteVideoConfig( void )
|
|||
{
|
||||
file_t *f;
|
||||
|
||||
MsgDev( D_NOTE, "Host_WriteVideoConfig()\n" );
|
||||
f = FS_Open( "video.cfg", "w", false );
|
||||
if( Sys_CheckParm( "-nowriteconfig" ) )
|
||||
return;
|
||||
|
||||
f = FS_Open( "video.cfg.new", "w", false );
|
||||
if( f )
|
||||
{
|
||||
Con_Reportf( "Host_WriteVideoConfig()\n" );
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
FS_Printf( f, "//\t\t\tCopyright XashXT Group %s (C)\n", Q_timestamp( TIME_YEAR_ONLY ));
|
||||
FS_Printf( f, "//\t\tvideo.cfg - archive of renderer variables\n");
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
Cvar_WriteVariables( f, FCVAR_RENDERINFO );
|
||||
FS_Close( f );
|
||||
CFG_END( f, "video.cfg" );
|
||||
}
|
||||
else MsgDev( D_ERROR, "can't update video.cfg.\n" );
|
||||
else Con_DPrintf( S_ERROR "can't update video.cfg.\n" );
|
||||
}
|
||||
#endif // XASH_DEDICATED
|
||||
|
||||
void Key_EnumCmds_f( void )
|
||||
{
|
||||
|
|
|
@ -12,6 +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.
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
@ -22,9 +23,6 @@ Sys_Crash
|
|||
Crash handler, called from system
|
||||
================
|
||||
*/
|
||||
#define DEBUG_BREAK
|
||||
/// TODO: implement on windows too
|
||||
|
||||
#if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP || XASH_CRASHHANDLER == CRASHHANDLER_WIN32
|
||||
#if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP
|
||||
#pragma comment( lib, "dbghelp" )
|
||||
|
@ -186,7 +184,7 @@ LPTOP_LEVEL_EXCEPTION_FILTER oldFilter;
|
|||
long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
|
||||
{
|
||||
// save config
|
||||
if( host.state != HOST_CRASHED )
|
||||
if( host.status != HOST_CRASHED )
|
||||
{
|
||||
// check to avoid recursive call
|
||||
host.crashed = true;
|
||||
|
@ -199,9 +197,9 @@ long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
|
|||
|
||||
if( host.type == HOST_NORMAL )
|
||||
CL_Crashed(); // tell client about crash
|
||||
else host.state = HOST_CRASHED;
|
||||
else host.status = HOST_CRASHED;
|
||||
|
||||
if( host.developer <= 0 )
|
||||
if( host_developer.value <= 0 )
|
||||
{
|
||||
// no reason to call debugger in release build - just exit
|
||||
Sys_Quit();
|
||||
|
@ -232,139 +230,187 @@ void Sys_RestoreCrashHandler( void )
|
|||
|
||||
#elif XASH_CRASHHANDLER == CRASHHANDLER_UCONTEXT
|
||||
// Posix signal handler
|
||||
|
||||
#include "library.h"
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined __ANDROID__
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__ANDROID__) || defined(__linux__)
|
||||
#define HAVE_UCONTEXT_H 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UCONTEXT_H
|
||||
#include <ucontext.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
int printframe( char *buf, int len, int i, void *addr )
|
||||
{
|
||||
Dl_info dlinfo;
|
||||
if( len <= 0 ) return 0; // overflow
|
||||
if( len <= 0 )
|
||||
return 0; // overflow
|
||||
|
||||
if( dladdr( addr, &dlinfo ))
|
||||
{
|
||||
if( dlinfo.dli_sname )
|
||||
return Q_snprintf( buf, len, "% 2d: %p <%s+%lu> (%s)\n", i, addr, dlinfo.dli_sname,
|
||||
return Q_snprintf( buf, len, "%2d: %p <%s+%lu> (%s)\n", i, addr, dlinfo.dli_sname,
|
||||
(unsigned long)addr - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname ); // print symbol, module and address
|
||||
else
|
||||
return Q_snprintf( buf, len, "% 2d: %p (%s)\n", i, addr, dlinfo.dli_fname ); // print module and address
|
||||
return Q_snprintf( buf, len, "%2d: %p (%s)\n", i, addr, dlinfo.dli_fname ); // print module and address
|
||||
}
|
||||
else
|
||||
return Q_snprintf( buf, len, "% 2d: %p\n", i, addr ); // print only address
|
||||
return Q_snprintf( buf, len, "%2d: %p\n", i, addr ); // print only address
|
||||
}
|
||||
|
||||
struct sigaction oldFilter;
|
||||
|
||||
#define STACK_BACKTRACE_STR_LEN 17
|
||||
#define STACK_BACKTRACE_STR "Stack backtrace:\n"
|
||||
#define STACK_DUMP_STR_LEN 12
|
||||
#define STACK_DUMP_STR "Stack dump:\n"
|
||||
#define ALIGN( x, y ) (((int) (x) + ((y)-1)) & ~((y)-1))
|
||||
|
||||
static void Sys_Crash( int signal, siginfo_t *si, void *context)
|
||||
{
|
||||
void *trace[32];
|
||||
void *pc, **bp, **sp; // this must be set for every OS!
|
||||
char message[8192];
|
||||
int len, logfd, i = 0;
|
||||
size_t pagesize;
|
||||
|
||||
char message[4096], stackframe[256];
|
||||
int len, stacklen, logfd, i = 0;
|
||||
#if defined(__OpenBSD__)
|
||||
struct sigcontext *ucontext = (struct sigcontext*)context;
|
||||
#else
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64__)
|
||||
#if defined(__FreeBSD__)
|
||||
void *pc = (void*)ucontext->uc_mcontext.mc_rip, **bp = (void**)ucontext->uc_mcontext.mc_rbp, **sp = (void**)ucontext->uc_mcontext.mc_rsp;
|
||||
pc = (void*)ucontext->uc_mcontext.mc_rip;
|
||||
bp = (void**)ucontext->uc_mcontext.mc_rbp;
|
||||
sp = (void**)ucontext->uc_mcontext.mc_rsp;
|
||||
#elif defined(__NetBSD__)
|
||||
void *pc = (void*)ucontext->uc_mcontext.__gregs[REG_RIP], **bp = (void**)ucontext->uc_mcontext.__gregs[REG_RBP], **sp = (void**)ucontext->uc_mcontext.__gregs[REG_RSP];
|
||||
pc = (void*)ucontext->uc_mcontext.__gregs[REG_RIP];
|
||||
bp = (void**)ucontext->uc_mcontext.__gregs[REG_RBP];
|
||||
sp = (void**)ucontext->uc_mcontext.__gregs[REG_RSP];
|
||||
#elif defined(__OpenBSD__)
|
||||
void *pc = (void*)ucontext->sc_rip, **bp = (void**)ucontext->sc_rbp, **sp = (void**)ucontext->sc_rsp;
|
||||
pc = (void*)ucontext->sc_rip;
|
||||
bp = (void**)ucontext->sc_rbp;
|
||||
sp = (void**)ucontext->sc_rsp;
|
||||
#else
|
||||
void *pc = (void*)ucontext->uc_mcontext.gregs[REG_RIP], **bp = (void**)ucontext->uc_mcontext.gregs[REG_RBP], **sp = (void**)ucontext->uc_mcontext.gregs[REG_RSP];
|
||||
pc = (void*)ucontext->uc_mcontext.gregs[REG_RIP];
|
||||
bp = (void**)ucontext->uc_mcontext.gregs[REG_RBP];
|
||||
sp = (void**)ucontext->uc_mcontext.gregs[REG_RSP];
|
||||
#endif
|
||||
#elif defined(__i386__)
|
||||
#if defined(__FreeBSD__)
|
||||
void *pc = (void*)ucontext->uc_mcontext.mc_eip, **bp = (void**)ucontext->uc_mcontext.mc_ebp, **sp = (void**)ucontext->uc_mcontext.mc_esp;
|
||||
pc = (void*)ucontext->uc_mcontext.mc_eip;
|
||||
bp = (void**)ucontext->uc_mcontext.mc_ebp;
|
||||
sp = (void**)ucontext->uc_mcontext.mc_esp;
|
||||
#elif defined(__NetBSD__)
|
||||
void *pc = (void*)ucontext->uc_mcontext.__gregs[REG_EIP], **bp = (void**)ucontext->uc_mcontext.__gregs[REG_EBP], **sp = (void**)ucontext->uc_mcontext.__gregs[REG_ESP];
|
||||
pc = (void*)ucontext->uc_mcontext.__gregs[REG_EIP];
|
||||
bp = (void**)ucontext->uc_mcontext.__gregs[REG_EBP];
|
||||
sp = (void**)ucontext->uc_mcontext.__gregs[REG_ESP];
|
||||
#elif defined(__OpenBSD__)
|
||||
void *pc = (void*)ucontext->sc_eip, **bp = (void**)ucontext->sc_ebp, **sp = (void**)ucontext->sc_esp;
|
||||
pc = (void*)ucontext->sc_eip;
|
||||
bp = (void**)ucontext->sc_ebp;
|
||||
sp = (void**)ucontext->sc_esp;
|
||||
#else
|
||||
void *pc = (void*)ucontext->uc_mcontext.gregs[REG_EIP], **bp = (void**)ucontext->uc_mcontext.gregs[REG_EBP], **sp = (void**)ucontext->uc_mcontext.gregs[REG_ESP];
|
||||
pc = (void*)ucontext->uc_mcontext.gregs[REG_EIP];
|
||||
bp = (void**)ucontext->uc_mcontext.gregs[REG_EBP];
|
||||
sp = (void**)ucontext->uc_mcontext.gregs[REG_ESP];
|
||||
#endif
|
||||
#elif defined(__aarch64__) // arm not tested
|
||||
void *pc = (void*)ucontext->uc_mcontext.pc, **bp = (void*)ucontext->uc_mcontext.regs[29], **sp = (void*)ucontext->uc_mcontext.sp;
|
||||
pc = (void*)ucontext->uc_mcontext.pc;
|
||||
bp = (void*)ucontext->uc_mcontext.regs[29];
|
||||
sp = (void*)ucontext->uc_mcontext.sp;
|
||||
#elif defined(__arm__)
|
||||
void *pc = (void*)ucontext->uc_mcontext.arm_pc, **bp = (void*)ucontext->uc_mcontext.arm_fp, **sp = (void*)ucontext->uc_mcontext.arm_sp;
|
||||
pc = (void*)ucontext->uc_mcontext.arm_pc;
|
||||
bp = (void*)ucontext->uc_mcontext.arm_fp;
|
||||
sp = (void*)ucontext->uc_mcontext.arm_sp;
|
||||
#else
|
||||
#error "Unknown arch!!!"
|
||||
#error "Unknown arch!!!"
|
||||
#endif
|
||||
// Safe actions first, stack and memory may be corrupted
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
len = Q_snprintf( message, 4096, "Sys_Crash: signal %d, err %d with code %d at %p\n", signal, si->si_errno, si->si_code, si->si_addr );
|
||||
#else
|
||||
len = Q_snprintf( message, 4096, "Sys_Crash: signal %d, err %d with code %d at %p %p\n", signal, si->si_errno, si->si_code, si->si_addr, si->si_ptr );
|
||||
#endif
|
||||
write(2, message, len);
|
||||
// Flush buffers before writing directly to descriptors
|
||||
|
||||
// safe actions first, stack and memory may be corrupted
|
||||
len = Q_snprintf( message, sizeof( message ), "Ver: %s %s (build %i-%s, %s-%s)\n",
|
||||
XASH_ENGINE_NAME, XASH_VERSION, Q_buildnum(), Q_buildcommit(), Q_buildos(), Q_buildarch() );
|
||||
|
||||
#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__)
|
||||
len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p %p\n", signal, si->si_errno, si->si_code, si->si_addr, si->si_ptr );
|
||||
#else
|
||||
len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p\n", signal, si->si_errno, si->si_code, si->si_addr );
|
||||
#endif
|
||||
|
||||
write( 2, message, len );
|
||||
|
||||
// flush buffers before writing directly to descriptors
|
||||
fflush( stdout );
|
||||
fflush( stderr );
|
||||
// Now get log fd and write trace directly to log
|
||||
|
||||
// now get log fd and write trace directly to log
|
||||
logfd = Sys_LogFileNo();
|
||||
write( logfd, message, len );
|
||||
write( 2, "Stack backtrace:\n", 17 );
|
||||
write( logfd, "Stack backtrace:\n", 17 );
|
||||
strncpy(message + len, "Stack backtrace:\n", 4096 - len);
|
||||
len += 17;
|
||||
size_t pagesize = sysconf(_SC_PAGESIZE);
|
||||
|
||||
// try to print backtrace
|
||||
write( 2, STACK_BACKTRACE_STR, STACK_BACKTRACE_STR_LEN );
|
||||
write( logfd, STACK_BACKTRACE_STR, STACK_BACKTRACE_STR_LEN );
|
||||
strncpy( message + len, STACK_BACKTRACE_STR, sizeof( message ) - len );
|
||||
len += STACK_BACKTRACE_STR_LEN;
|
||||
|
||||
pagesize = sysconf( _SC_PAGESIZE );
|
||||
|
||||
do
|
||||
{
|
||||
int line = printframe( message + len, 4096 - len, ++i, pc);
|
||||
int line = printframe( message + len, sizeof( message ) - len, ++i, pc);
|
||||
write( 2, message + len, line );
|
||||
write( logfd, message + len, line );
|
||||
len += line;
|
||||
//if( !dladdr(bp,0) ) break; // Only when bp is in module
|
||||
if( ( mprotect((char *)(((int) bp + (pagesize-1)) & ~(pagesize-1)), pagesize, PROT_READ | PROT_WRITE | PROT_EXEC ) == -1) &&
|
||||
( mprotect((char *)(((int) bp + (pagesize-1)) & ~(pagesize-1)), pagesize, PROT_READ | PROT_EXEC ) == -1) &&
|
||||
( mprotect((char *)(((int) bp + (pagesize-1)) & ~(pagesize-1)), pagesize, PROT_READ | PROT_WRITE ) == -1) &&
|
||||
( mprotect((char *)(((int) bp + (pagesize-1)) & ~(pagesize-1)), pagesize, PROT_READ ) == -1) )
|
||||
//if( !dladdr(bp,0) ) break; // only when bp is in module
|
||||
if( ( mprotect( (char *)ALIGN( bp, pagesize ), pagesize, PROT_READ | PROT_WRITE | PROT_EXEC ) == -1) &&
|
||||
( mprotect( (char *)ALIGN( bp, pagesize ), pagesize, PROT_READ | PROT_EXEC ) == -1) &&
|
||||
( mprotect( (char *)ALIGN( bp, pagesize ), pagesize, PROT_READ | PROT_WRITE ) == -1) &&
|
||||
( mprotect( (char *)ALIGN( bp, pagesize ), pagesize, PROT_READ ) == -1) )
|
||||
break;
|
||||
if( ( mprotect((char *)(((int) bp[0] + (pagesize-1)) & ~(pagesize-1)), pagesize, PROT_READ | PROT_WRITE | PROT_EXEC ) == -1) &&
|
||||
( mprotect((char *)(((int) bp[0] + (pagesize-1)) & ~(pagesize-1)), pagesize, PROT_READ | PROT_EXEC ) == -1) &&
|
||||
( mprotect((char *)(((int) bp[0] + (pagesize-1)) & ~(pagesize-1)), pagesize, PROT_READ | PROT_WRITE ) == -1) &&
|
||||
( mprotect((char *)(((int) bp[0] + (pagesize-1)) & ~(pagesize-1)), pagesize, PROT_READ ) == -1) )
|
||||
if( ( mprotect( (char *)ALIGN( bp[0], pagesize ), pagesize, PROT_READ | PROT_WRITE | PROT_EXEC ) == -1) &&
|
||||
( mprotect( (char *)ALIGN( bp[0], pagesize ), pagesize, PROT_READ | PROT_EXEC ) == -1) &&
|
||||
( mprotect( (char *)ALIGN( bp[0], pagesize ), pagesize, PROT_READ | PROT_WRITE ) == -1) &&
|
||||
( mprotect( (char *)ALIGN( bp[0], pagesize ), pagesize, PROT_READ ) == -1) )
|
||||
break;
|
||||
pc = bp[1];
|
||||
bp = (void**)bp[0];
|
||||
}
|
||||
while( bp && i < 128 );
|
||||
// Try to print stack
|
||||
write( 2, "Stack dump:\n", 12 );
|
||||
write( logfd, "Stack dump:\n", 12 );
|
||||
strncpy( message + len, "Stack dump:\n", 4096 - len );
|
||||
|
||||
len += 12;
|
||||
if( ( mprotect((char *)(((int) sp + (pagesize-1)) & ~(pagesize-1)), pagesize, PROT_READ | PROT_WRITE | PROT_EXEC ) != -1) ||
|
||||
( mprotect((char *)(((int) sp + (pagesize-1)) & ~(pagesize-1)), pagesize, PROT_READ | PROT_EXEC ) != -1) ||
|
||||
( mprotect((char *)(((int) sp + (pagesize-1)) & ~(pagesize-1)), pagesize, PROT_READ | PROT_WRITE ) != -1) ||
|
||||
( mprotect((char *)(((int) sp + (pagesize-1)) & ~(pagesize-1)), pagesize, PROT_READ ) != -1) )
|
||||
// try to print stack
|
||||
write( 2, STACK_DUMP_STR, STACK_DUMP_STR_LEN );
|
||||
write( logfd, STACK_DUMP_STR, STACK_DUMP_STR_LEN );
|
||||
strncpy( message + len, STACK_DUMP_STR, sizeof( message ) - len );
|
||||
len += STACK_DUMP_STR_LEN;
|
||||
|
||||
if( ( mprotect((char *)ALIGN( sp, pagesize ), pagesize, PROT_READ | PROT_WRITE | PROT_EXEC ) != -1) ||
|
||||
( mprotect((char *)ALIGN( sp, pagesize ), pagesize, PROT_READ | PROT_EXEC ) != -1) ||
|
||||
( mprotect((char *)ALIGN( sp, pagesize ), pagesize, PROT_READ | PROT_WRITE ) != -1) ||
|
||||
( mprotect((char *)ALIGN( sp, pagesize ), pagesize, PROT_READ ) != -1) )
|
||||
{
|
||||
for( i = 0; i < 32; i++ )
|
||||
{
|
||||
int line = printframe( message + len, 4096 - len, i, sp[i] );
|
||||
int line = printframe( message + len, sizeof( message ) - len, i, sp[i] );
|
||||
write( 2, message + len, line );
|
||||
write( logfd, message + len, line );
|
||||
len += line;
|
||||
}
|
||||
// Put MessageBox as Sys_Error
|
||||
}
|
||||
|
||||
// put MessageBox as Sys_Error
|
||||
Msg( "%s\n", message );
|
||||
#ifdef XASH_SDL
|
||||
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
|
||||
#endif
|
||||
MSGBOX( message );
|
||||
|
||||
// Log saved, now we can try to save configs and close log correctly, it may crash
|
||||
// log saved, now we can try to save configs and close log correctly, it may crash
|
||||
if( host.type == HOST_NORMAL )
|
||||
CL_Crashed();
|
||||
host.state = HOST_CRASHED;
|
||||
host.status = HOST_CRASHED;
|
||||
host.crashed = true;
|
||||
|
||||
Sys_Quit();
|
||||
|
@ -375,10 +421,10 @@ void Sys_SetupCrashHandler( void )
|
|||
struct sigaction act;
|
||||
act.sa_sigaction = Sys_Crash;
|
||||
act.sa_flags = SA_SIGINFO | SA_ONSTACK;
|
||||
sigaction(SIGSEGV, &act, &oldFilter);
|
||||
sigaction(SIGABRT, &act, &oldFilter);
|
||||
sigaction(SIGBUS, &act, &oldFilter);
|
||||
sigaction(SIGILL, &act, &oldFilter);
|
||||
sigaction( SIGSEGV, &act, &oldFilter );
|
||||
sigaction( SIGABRT, &act, &oldFilter );
|
||||
sigaction( SIGBUS, &act, &oldFilter );
|
||||
sigaction( SIGILL, &act, &oldFilter );
|
||||
}
|
||||
|
||||
void Sys_RestoreCrashHandler( void )
|
||||
|
|
|
@ -422,7 +422,7 @@ void MD5Final( byte digest[16], MD5Context_t *ctx )
|
|||
|
||||
MD5Transform( ctx->buf, (uint *)ctx->in );
|
||||
memcpy( digest, ctx->buf, 16 );
|
||||
memset( ctx, 0, sizeof( ctx )); // in case it's sensitive
|
||||
memset( ctx, 0, sizeof( *ctx )); // in case it's sensitive
|
||||
}
|
||||
|
||||
// The four core functions
|
||||
|
|
|
@ -185,7 +185,7 @@ char *_copystring( byte *mempool, const char *s, const char *filename, int filel
|
|||
if( !s ) return NULL;
|
||||
if( !mempool ) mempool = host.mempool;
|
||||
|
||||
b = _Mem_Alloc( mempool, Q_strlen( s ) + 1, filename, fileline );
|
||||
b = _Mem_Alloc( mempool, Q_strlen( s ) + 1, false, filename, fileline );
|
||||
Q_strcpy( b, s );
|
||||
|
||||
return b;
|
||||
|
@ -575,7 +575,6 @@ int Q_vsnprintf( char *buffer, size_t buffersize, const char *format, va_list ar
|
|||
__except( EXCEPTION_EXECUTE_HANDLER )
|
||||
{
|
||||
Q_strncpy( buffer, "^1sprintf throw exception^7\n", buffersize );
|
||||
// memset( buffer, 0, buffersize );
|
||||
result = buffersize;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,7 @@ enum
|
|||
#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 );
|
||||
|
||||
|
@ -54,6 +55,7 @@ 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 );
|
||||
|
@ -113,8 +115,8 @@ char *va( const char *format, ... ) _format( 1 );
|
|||
// zone.c
|
||||
//
|
||||
void Memory_Init( void );
|
||||
void *_Mem_Realloc( byte *poolptr, void *memptr, size_t size, const char *filename, int fileline );
|
||||
void *_Mem_Alloc( byte *poolptr, size_t size, const char *filename, int fileline );
|
||||
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 );
|
||||
|
@ -124,8 +126,9 @@ qboolean Mem_IsAllocatedExt( byte *poolptr, void *data );
|
|||
void Mem_PrintList( size_t minallocationsize );
|
||||
void Mem_PrintStats( void );
|
||||
|
||||
#define Mem_Alloc( pool, size ) _Mem_Alloc( pool, size, __FILE__, __LINE__ )
|
||||
#define Mem_Realloc( pool, ptr, size ) _Mem_Realloc( pool, ptr, size, __FILE__, __LINE__ )
|
||||
#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__ )
|
||||
|
|
|
@ -63,12 +63,12 @@ void COM_ClearCustomizationList( customization_t *pHead, qboolean bCleanDecals )
|
|||
qboolean COM_CreateCustomization( customization_t *pListHead, resource_t *pResource, int playernumber, int flags, customization_t **pOut, int *nLumps )
|
||||
{
|
||||
qboolean bError = false;
|
||||
long checksize = 0;
|
||||
size_t checksize = 0;
|
||||
customization_t *pCust;
|
||||
|
||||
if( pOut ) *pOut = NULL;
|
||||
|
||||
pCust = Z_Malloc( sizeof( customization_t ));
|
||||
pCust = Z_Calloc( sizeof( customization_t ));
|
||||
pCust->resource = *pResource;
|
||||
|
||||
if( pResource->nDownloadSize <= 0 )
|
||||
|
|
|
@ -13,8 +13,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <math.h> // fabs...
|
||||
#include "common.h"
|
||||
#include "math.h" // fabs...
|
||||
#include "base_cmd.h"
|
||||
|
||||
convar_t *cvar_vars = NULL; // head of list
|
||||
convar_t *cmd_scripting;
|
||||
|
@ -39,6 +40,10 @@ find the specified variable by name
|
|||
*/
|
||||
convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group )
|
||||
{
|
||||
// TODO: ignore group for cvar
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
return (convar_t *)BaseCmd_Find( HM_CVAR, var_name );
|
||||
#else
|
||||
convar_t *var;
|
||||
|
||||
if( !var_name )
|
||||
|
@ -54,6 +59,7 @@ convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group )
|
|||
}
|
||||
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -115,6 +121,7 @@ static qboolean Cvar_UpdateInfo( convar_t *var, const char *value, qboolean noti
|
|||
|
||||
// time to update server copy of userinfo
|
||||
CL_ServerCommand( true, "setinfo \"%s\" \"%s\"\n", var->name, value );
|
||||
CL_LegacyUpdateInfo();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -238,6 +245,10 @@ int Cvar_UnlinkVar( const char *var_name, int group )
|
|||
continue;
|
||||
}
|
||||
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
BaseCmd_Remove( HM_CVAR, var->name );
|
||||
#endif
|
||||
|
||||
// unlink variable from list
|
||||
freestring( var->string );
|
||||
*prev = var->next;
|
||||
|
@ -333,7 +344,7 @@ convar_t *Cvar_Get( const char *name, const char *value, int flags, const char *
|
|||
// check for command coexisting
|
||||
if( Cmd_Exists( name ))
|
||||
{
|
||||
MsgDev( D_ERROR, "can't register variable '%s', is already defined as command\n", name );
|
||||
Con_DPrintf( S_ERROR "can't register variable '%s', is already defined as command\n", name );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -369,7 +380,7 @@ convar_t *Cvar_Get( const char *name, const char *value, int flags, const char *
|
|||
if( FBitSet( var->flags, FCVAR_ALLOCATED ) && Q_strcmp( var_desc, var->desc ))
|
||||
{
|
||||
if( !FBitSet( flags, FCVAR_GLCONFIG ))
|
||||
MsgDev( D_REPORT, "%s change description from %s to %s\n", var->name, var->desc, var_desc );
|
||||
Con_Reportf( "%s change description from %s to %s\n", var->name, var->desc, var_desc );
|
||||
// update description if needs
|
||||
freestring( var->desc );
|
||||
var->desc = copystring( var_desc );
|
||||
|
@ -400,6 +411,11 @@ convar_t *Cvar_Get( const char *name, const char *value, int flags, const char *
|
|||
// tell engine about changes
|
||||
Cvar_Changed( var );
|
||||
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
// add to map
|
||||
BaseCmd_Insert( HM_CVAR, var, var->name );
|
||||
#endif
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
|
@ -423,7 +439,7 @@ void Cvar_RegisterVariable( convar_t *var )
|
|||
{
|
||||
if( !FBitSet( dup->flags, FCVAR_TEMPORARY ))
|
||||
{
|
||||
MsgDev( D_ERROR, "can't register variable '%s', is already defined\n", var->name );
|
||||
Con_DPrintf( S_ERROR "can't register variable '%s', is already defined\n", var->name );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -434,7 +450,7 @@ void Cvar_RegisterVariable( convar_t *var )
|
|||
// check for overlap with a command
|
||||
if( Cmd_Exists( var->name ))
|
||||
{
|
||||
MsgDev( D_ERROR, "can't register variable '%s', is already defined as command\n", var->name );
|
||||
Con_DPrintf( S_ERROR "can't register variable '%s', is already defined as command\n", var->name );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -463,6 +479,11 @@ void Cvar_RegisterVariable( convar_t *var )
|
|||
|
||||
// tell engine about changes
|
||||
Cvar_Changed( var );
|
||||
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
// add to map
|
||||
BaseCmd_Insert( HM_CVAR, var, var->name );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -482,16 +503,12 @@ void Cvar_DirectSet( convar_t *var, const char *value )
|
|||
if( CVAR_CHECK_SENTINEL( var ) || ( var->next == NULL && !FBitSet( var->flags, FCVAR_EXTENDED|FCVAR_ALLOCATED )))
|
||||
{
|
||||
// need to registering cvar fisrt
|
||||
MsgDev( D_WARN, "Cvar_DirectSet: called for unregistered cvar '%s'\n", var->name );
|
||||
Cvar_RegisterVariable( var ); // ok, register it
|
||||
}
|
||||
|
||||
// lookup for registration again
|
||||
if( var != Cvar_FindVar( var->name ))
|
||||
{
|
||||
MsgDev( D_ERROR, "Cvar_DirectSet: couldn't find cvar '%s' in linked list\n", var->name );
|
||||
return;
|
||||
}
|
||||
return; // how this possible?
|
||||
|
||||
if( FBitSet( var->flags, FCVAR_READ_ONLY|FCVAR_GLCONFIG ))
|
||||
{
|
||||
|
@ -578,8 +595,7 @@ void Cvar_Set( const char *var_name, const char *value )
|
|||
if( !var )
|
||||
{
|
||||
// there is an error in C code if this happens
|
||||
if( host.type != HOST_DEDICATED )
|
||||
MsgDev( D_ERROR, "Cvar_Set: variable '%s' not found\n", var_name );
|
||||
Con_Printf( "Cvar_Set: variable '%s' not found\n", var_name );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -657,6 +673,18 @@ const char *Cvar_VariableString( const char *var_name )
|
|||
return var->string;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_Exists
|
||||
============
|
||||
*/
|
||||
qboolean Cvar_Exists( const char *var_name )
|
||||
{
|
||||
if( Cvar_FindVar( var_name ))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_SetCheatState
|
||||
|
@ -683,6 +711,26 @@ void Cvar_SetCheatState( void )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_SetGL
|
||||
|
||||
As Cvar_Set, but also flags it as glconfig
|
||||
============
|
||||
*/
|
||||
static void Cvar_SetGL( const char *name, const char *value )
|
||||
{
|
||||
convar_t *var = Cvar_FindVar( name );
|
||||
|
||||
if( var && !FBitSet( var->flags, FCVAR_GLCONFIG ))
|
||||
{
|
||||
Con_Reportf( S_ERROR "Can't set non-GL cvar %s to %s\n", name, value );
|
||||
return;
|
||||
}
|
||||
|
||||
Cvar_FullSet( name, value, FCVAR_GLCONFIG );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_Command
|
||||
|
@ -690,18 +738,17 @@ Cvar_Command
|
|||
Handles variable inspection and changing from the console
|
||||
============
|
||||
*/
|
||||
qboolean Cvar_Command( void )
|
||||
qboolean Cvar_Command( convar_t *v )
|
||||
{
|
||||
convar_t *v;
|
||||
|
||||
// special case for setup opengl configuration
|
||||
if( host.apply_opengl_config )
|
||||
{
|
||||
Cvar_FullSet( Cmd_Argv( 0 ), Cmd_Argv( 1 ), FCVAR_GLCONFIG );
|
||||
Cvar_SetGL( Cmd_Argv( 0 ), Cmd_Argv( 1 ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
// check variables
|
||||
if( !v ) // already found in basecmd
|
||||
v = Cvar_FindVar( Cmd_Argv( 0 ));
|
||||
if( !v ) return false;
|
||||
|
||||
|
@ -785,13 +832,15 @@ As Cvar_Set, but also flags it as glconfig
|
|||
*/
|
||||
void Cvar_SetGL_f( void )
|
||||
{
|
||||
convar_t *var;
|
||||
|
||||
if( Cmd_Argc() != 3 )
|
||||
{
|
||||
Con_Printf( S_USAGE "setgl <variable> <value>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
Cvar_FullSet( Cmd_Argv( 1 ), Cmd_Argv( 2 ), FCVAR_GLCONFIG );
|
||||
Cvar_SetGL( Cmd_Argv( 1 ), Cmd_Argv( 2 ) );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -884,7 +933,7 @@ void Cvar_Init( void )
|
|||
cmd_scripting = Cvar_Get( "cmd_scripting", "0", FCVAR_ARCHIVE, "enable simple condition checking and variable operations" );
|
||||
Cvar_RegisterVariable (&host_developer); // early registering for dev
|
||||
|
||||
Cmd_AddCommand( "setgl", Cvar_SetGL_f, "create or change the value of a opengl variable" ); // OBSOLETE
|
||||
Cmd_AddCommand( "setgl", Cvar_SetGL_f, "change the value of a opengl variable" ); // OBSOLETE
|
||||
Cmd_AddCommand( "toggle", Cvar_Toggle_f, "toggles a console variable's values (use for more info)" );
|
||||
Cmd_AddCommand( "reset", Cvar_Reset_f, "reset any type variable to initial value" );
|
||||
Cmd_AddCommand( "cvarlist", Cvar_List_f, "display all console variables beginning with the specified prefix" );
|
||||
|
|
|
@ -43,6 +43,7 @@ typedef struct convar_s
|
|||
#define FCVAR_ALLOCATED (1<<19) // this convar_t is fully dynamic allocated (include description)
|
||||
#define FCVAR_VIDRESTART (1<<20) // recreate the window is cvar with this flag was changed
|
||||
#define FCVAR_TEMPORARY (1<<21) // these cvars holds their values and can be unlink in any time
|
||||
#define FCVAR_LOCALONLY (1<<22) // can be set only from local buffers
|
||||
|
||||
#define CVAR_DEFINE( cv, cvname, cvstr, cvflags, cvdesc ) convar_t cv = { cvname, cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, cvdesc }
|
||||
#define CVAR_DEFINE_AUTO( cv, cvstr, cvflags, cvdesc ) convar_t cv = { #cv, cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, cvdesc }
|
||||
|
@ -63,9 +64,10 @@ float Cvar_VariableValue( const char *var_name );
|
|||
int Cvar_VariableInteger( const char *var_name );
|
||||
const char *Cvar_VariableString( const char *var_name );
|
||||
void Cvar_WriteVariables( file_t *f, int group );
|
||||
qboolean Cvar_Exists( const char *var_name );
|
||||
void Cvar_Reset( const char *var_name );
|
||||
void Cvar_SetCheatState( void );
|
||||
qboolean Cvar_Command( void );
|
||||
qboolean Cvar_Command( convar_t *v );
|
||||
void Cvar_Init( void );
|
||||
void Cvar_Unlink( int group );
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue